[英]C# Web Api rest linq query return too much data
Good day, I run into the problem then returning DTO object. I have these classes美好的一天,我遇到问题然后返回 DTO object。我有这些课程
public class ProductBase
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public IEnumerable<ProductVariant> Variants { get; set; }
public int BaseImageId { get; set; } = 0;
}
public class ProductVariant
{
public int Id { get; set; }
public int Quantity { get; set; }
public int ProductBaseId { get; set; }
public ProductBase productBase { get; set; }
public int ProductSizeId { get; set; }
public ProductSize ProductSize { get; set; }
public int ProductColorId { get; set; }
public ProductColor ProductColor { get; set; }
public IEnumerable<ImageVariant> imageVariants { get; set; }
}
public class ProductColor
{
public int Id { get; set; }
public string Color { get; set; }
public IEnumerable<ProductVariant> productVariant { get; set; }
}
public class ProductSize
{
public int Id { get; set; }
public string Size { get; set; }
public IEnumerable<ProductVariant> productVariant { get; set; }
}
In productBaseRepository I have this call在 productBaseRepository 我有这个电话
public async Task<IEnumerable<Models.ProductBase>> GetAllWithVariantsAsync()
{
var result = await _dataContext.ProductBases
.Include(pb => pb.Variants)
.ThenInclude(v => v.ProductSize)
.Include(pb => pb.Variants)
.ThenInclude(v => v.ProductColor)
.ToListAsync();
return result;
}
I have created DTO convertion function我创建了 DTO 转换 function
public static IEnumerable<ProductBaseDTO> ConvertToDto(this IEnumerable<ProductBase> productBases)
{
var returnProductBaseDto = (from product in productBases
select new ProductBaseDTO
{
Id = product.Id,
Name = product.Name,
Variants = product.Variants.ToList(),
Description = product.Description,
BaseImageId = product.BaseImageId,
}).ToList();
return returnProductBaseDto;
}
But then I call this function from swagger但后来我从 swagger 调用这个 function
[HttpGet]
public async Task<ActionResult<List<ProductBaseDTO>>> GetAllProductsWithVariants()
{
var baseProductDomain = await _productBaseRepository.GetAllWithVariantsAsync();
var baseProduct = baseProductDomain.ConvertToDto();
return Ok(baseProduct);
}
I get that System.Text.Json.JsonException: A possible object cycle was detected.我得到 System.Text.Json.JsonException: A possible object cycle was detected. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32
这可能是由于循环或 object 深度大于最大允许深度 32
If I remove variants from call it works, so I need to some how remove Unecessry values from Variants如果我从调用中删除变体它会起作用,所以我需要一些如何从变体中删除不必要的值
The problem happens because your ProductVariant
references ProductSize
and ProductColor
and ProductSize
and ProductColor
reference a list of ProductVariant
objects.出现此问题是因为您的
ProductVariant
引用了ProductSize
和ProductColor
,而ProductSize
和ProductColor
引用了ProductVariant
对象的列表。 And ProductVariant
has a reference to its BaseProduct
. ProductVariant
引用了它的BaseProduct
。 This creates a cycle, two objects referencing each other.这创建了一个循环,两个对象相互引用。
In order to solve this issue, remove productVariant
List from ProductSize
and ProductColor
or remove the ProductSize
and ProductColor
references from ProductVariant
.为了解决此问题,请从
ProductSize
和ProductColor
中删除productVariant
List 或从ProductVariant
中删除ProductSize
和ProductColor
引用。 Also remove the productBase
reference from ProductVariant
.同时从
ProductVariant
中删除productBase
引用。
Use the IDs to find object references if required instead of having circular object references.如果需要,使用 ID 查找 object 引用,而不是循环引用 object。
See prevent property from being serialized in web API on how to prevent properties from being serialized without removing the property declaration from the class.请参阅web API 中的防止属性被序列化,了解如何在不从 class 中删除属性声明的情况下防止属性被序列化。
This is because Variants
has a reference to its parents type, You could simply set this to null, eg这是因为
Variants
有一个对其父类型的引用,您可以简单地将其设置为 null,例如
foreach(var x in baseProduct.SelectMany(c => c.Variants) { x.ProductBase = null }
We ussually have different viewmodels to stop these cycles, eg:我们通常有不同的视图模型来停止这些循环,例如:
public class Order {
public List<OrderLine> OrderLines {get;set}
}
public class OrderLine {
public Order Order {get;set}
}
// Gets mapped to the following viewmodels:
public class OrderViewModel {
public List<OrderOrderLineViewModel > OrderLines {get;set}
}
public class OrderOrderLineViewModel {
public Order Order => null; // Stop object cycling
}
Note that the exception message should tell you where the issue is for example $.Variants.productBase.variants.productBase.variants
or something similar.请注意,异常消息应该告诉您问题出在哪里,例如
$.Variants.productBase.variants.productBase.variants
或类似的东西。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.