Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Self referencing loop detected for property in WebApi 2

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);
}

Product class

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; }
}

Review class

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; }
}

entity diagram

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
            }
        ]
}

Which shows following error:

"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'.

How can I resolve this error?

like image 553
LogicalDesk Avatar asked Dec 02 '22 12:12

LogicalDesk


1 Answers

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.

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;

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 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.

Reference captured from, http://www.newtonsoft.com/json/help/html/SerializationSettings.htm

like image 116
Afzaal Ahmad Zeeshan Avatar answered Dec 15 '22 06:12

Afzaal Ahmad Zeeshan