.net circularReferenceException转换为JSON时.如何限制引用

本文关键字:何限制 引用 JSON circularReferenceException 转换 net | 更新日期: 2023-09-27 18:18:26

我有两个模型类,Address和Product,它们在数据库上是多对多关系。

当我尝试使用Include()加载地址来获取产品时,当我试图将其转换为JSON时,我会得到一个循环参考异常。这是完全合理的,JSON将变得无限长。

我知道,我可以把[ScriptIgnore]放在一个引用列表的顶部来解决这个问题。

但这会导致一个新问题:我需要解决两个方向的关系,并根据情况将它们放入JSON中。我的意思是,根据情况,我需要产品和引用的地址;在另一点上,我需要地址和它们的产品引用;

以下是我的课程(缩短):

public class Product
{
    ...
    [ScriptIgnore]
    public List<Address> Addresses { get; set; }
}

Address类:

   public class Address
{
    ....
    public List<Product> Products { get; set; }
    ...
}

获取数据:

        public JsonResult GetAllOrders()
    {
        EFDbContext context = new EFDbContext();
        return Json(context.Addresses.Include(a => a.Products).ToList(), JsonRequestBehavior.AllowGet);
    }

是否有一种方法可以告诉序列化器忽略哪些引用,尊重哪些引用?在上述情况下,我希望地址->产品引用被尊重,但其子产品->地址被忽略。

我想到的唯一解决方案是遍历每个地址及其Product并删除引用。但是我希望有一种更优雅的方式

.net circularReferenceException转换为JSON时.如何限制引用

您需要遍历一个没有循环引用的新对象。例如:

public static object ToAnonymousType(this Address address)
{
    var products = address.Products.Select(p => p.ToAnonymousType());
    return new { Id = address.Id, Products=products };
}
public static object ToAnonymousType(this Product product)
{
    return new { Id = product.Id };
}
public JsonResult GetAllOrders()
{
    using(var context = new EFDbContext())
    {
        var addresses = context.Addresses.Include(a => a.Products).ToList().Select(a => a.ToAnonymousType());
        return Json(addresses, JsonRequestBehavior.AllowGet);
    }
}

在这段代码中,您没有像这样定义virtual关键字:

public virtual IList<Product> Products { get; set; }

所以对于这个看起来不错的部分,不要添加虚拟关键字。

如果你需要使用Include使属性加载,这意味着延迟加载被禁用,但以防万一,你可以尝试强制禁用它

public class EFDbContext: DbContext 
{ 
    public EFDbContext() 
    { 
        this.Configuration.LazyLoadingEnabled = false; 
    } 
}

还有一件事是你为Addresses属性添加了[ScriptIgnore],但是把它也添加到Products呢?

public class Address
{
    ....
    [ScriptIgnore]
    public List<Product> Products { get; set; }
    ...
}

您应该查看此链接以获取更多说明:加载相关实体