在WebApi 2中检测到属性的自引用循环 [英] Self referencing loop detected for property in WebApi 2

查看:255
本文介绍了在WebApi 2中检测到属性的自引用循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个Web Api,用于将新产品和评论保存在数据库中。下面是WebApi代码:

I've created a Web Api to save new products and reviews in database. Below is the WebApi code:

// POST api/Products
        [ResponseType(typeof(Product))]
        public IHttpActionResult PostProduct(Product product)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            db.Products.Add(product);
            db.SaveChanges();

            return CreatedAtRoute("DefaultApi", new { id = product.ProductId }, product);
        }

产品类别-

public class Product
    {
        public int ProductId { get; set; }
          [Required]
        public string Name { get; set; }
        public string Category { get; set; }
        public int Price { get; set; }
        //Navigation Property
        public ICollection<Review> Reviews { get; set; }
    }

评论课-

public class Review
    {
        public int ReviewId { get; set; }
        public int ProductId { get; set; }
          [Required]
        public string Title { get; set; }
        public string Description { get; set; }
        //Navigation Property
        public Product Product { get; set; }
    }

我正在使用Google Chrome扩展程序 POSTMAN来测试api。当我尝试通过在POSTMAN中创建POST请求来保存详细信息时:

I'm using google chrome extension 'POSTMAN' to test the api. When I try to save details by creating a POST request in POSTMAN:

{
    "Name": "Product 4",
        "Category": "Category 4",
        "Price": 200,
        "Reviews": [
            {
                "ReviewId": 1,
                "ProductId": 1,
                "Title": "Review 1",
                "Description": "Test review 1",
                "Product": null
            },
            {
                "ReviewId": 2,
                "ProductId": 1,
                "Title": "Review 2",
                "Description": "Test review 2",
                "Product": null
            }
        ]
}

它显示以下错误-


Message:发生了错误。, ExceptionMessage:
'ObjectContent`1'类型未能序列化
内容类型'application / json;
的响应主体charset = utf-8'。, ExceptionType: System.InvalidOperationException, StackTrace:null, InnerException:{ Message:发生了
错误。, ExceptionMessage: 检测到类型为
'HelloWebAPI.Models.Product'的属性'Product'的自引用循环

"Message":"An error has occurred.","ExceptionMessage":"The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'.","ExceptionType":"System.InvalidOperationException","StackTrace":null,"InnerException":{"Message":"An error has occurred.","ExceptionMessage":"Self referencing loop detected for property 'Product' with type 'HelloWebAPI.Models.Product'.

如何解决此错误?

推荐答案

首先,将Navigation属性更改为 virtual

First of all, change the Navigation properties to virtual, that would provide lazy loading,

public virtual ICollection<Review> Reviews { get; set; }

// In the review, make some changes as well
public virtual Product Product { get; set; }

第二,因为您知道产品集合中不会总是有一个评论,难道不能将它设置为可空吗? —

Secondly, since you know that a Product is not going to always have a review in the collection, can't you set it to nullable? — just saying.

现在回到您的问题,处理此问题的一种非常简单的方法就是忽略无法序列化的对象再次!使用Json.NET的 JsonSerializer 中的 ReferenceLoopHandling.Ignore 设置来执行此操作。对于ASP.NET Web API,可以进行全局设置(取自此SO线程),

Now back to your question, a pretty much easy way to handle this would be to just ignore the objects which cannot be serialized... Again! Do that using the ReferenceLoopHandling.Ignore setting in the JsonSerializer of Json.NET. For ASP.NET Web API, a global setting can be done (taken from this SO thread),

GlobalConfiguration.Configuration.Formatters
                   .JsonFormatter.SerializerSettings.Re‌​ferenceLoopHandling 
                   = ReferenceLoopHandling.Ignore;

此错误来自Json.NET,当它尝试序列化已被序列化的对象时(

This error comes from Json.NET when it tried to serialize an object, which had already been serialized (your loop of objects!), and the documentation makes this pretty much clear as well,


Json.NET将忽略引用循环中的对象,并且不序列化它们。第一次遇到对象时,它将像往常一样进行序列化,但是如果将该对象作为其本身的子对象遇到,则序列化程序将跳过对其进行序列化。

Json.NET will ignore objects in reference loops and not serialize them. The first time an object is encountered it will be serialized as usual but if the object is encountered as a child object of itself the serializer will skip serializing it.

引用来自 http://www.newtonsoft.com/ json / help / html / SerializationSettings.htm

这篇关于在WebApi 2中检测到属性的自引用循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆