为 WebApi 2 中的属性检测到自引用循环检测到、属性、WebApi

由网友(每一段路都是一种领悟)分享简介:我创建了一个 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[...

我创建了一个 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":"TheObjectContent`1"类型无法序列化响应正文内容类型'应用程序/json;charset=utf-8'.","ExceptionType":"System.InvalidOperationException","StackTrace":null,"InnerException":{"Message":"An发生错误.","ExceptionMessage":"自引用循环检测到具有类型的属性产品"'HelloWebAPI.Models.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; }

其次,既然您知道 Product 在集合中不会总是有评论,那么您不能将其设置为可空吗?—只是说.

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,可以进行全局设置(取自 this SO thread),

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

阅读全文

相关推荐

最新文章