c# - Self referencing loop detected (Solved 2-Ways)

Getting around C# self-referencing loop exception
Sometimes we come across this kind of error when building web apps. This kind of error occurs when we have multiple navigational properties in the model and EF cannot parse the relational objects. The best way to overcome this is to use the Newtonsoft library to parse it to a string, use a DTO object or anonymous types to pass the data required or set this in the Global.asax file to ignore reference loop handling
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;

The Model class
If you have a product model class that has a navigational property Category, it would be hard for EF to parse the results of both properties to the view. Take a product class for example:
public class Product{
   public int Id { get; set; }
   public string Name{ get; set; }
   public decimal Price{ get; set; }
   public virtual Category Category { get; set; }
}
The product class has another navigational class “Category” which has other properties.

public class Category{
  public Category(){
            Products = new HashSet<Product>();
  }
   public int Id { get; set; }
   public string Name{ get; set; }
   public virtual ICollection<Product> Products { get; set; }
}

If you try to use a DbContext object to get the result for products in asp.net web api project, it will throw an error message when there is data in both tables:
Var db = new DbContext();
return Ok(db.Products); //This would not work

Using Anonymous Types  
var products = db.Products.Select(p=>new{
            p.Name,
            p.Price,
            CategoryName = p.Category.Name
});
return Ok(products);

Using Dto’s

Using Dto is simple, you just need to create a class and pass the required data.
Public class ProductDTO{
            public string Name{get;set;}
            public string Price{get;set;}
            public string CategoryName{get;set;}
}
And do it this way:

var products = db.Products.Select(p=>new ProductDTO{
            Name = p.Name,
            Price = p.Price,
            CategoryName = p.Category.Name
});
return Ok(products);


But I prefer using anonymous type because it just detect the name and you can also specify a custom name. Using the second option has a drawback. It uses the properties defined in the class to pass the data from the database but if there is a property that is not assigned, it would return it empty in the output.

Comments

Popular posts from this blog

Solved: Jwt Authentication in Asp.Net Web Api And Mvc

Sending Notification Message with Firebase with JavaScript and .Net client

Using SignalR with Unity