3

I am getting an error while executing an application using MVC4, Web API, AngularJS . The error is following:

Self referencing loop detected with type 
    'System.Data.Entity.DynamicProxies.Product_259FEB40BD6111F44AA3C3CED8DD40E7E44B22CC11A32AE621E84E2239F79B2C'. Path '[0].category.products'.

My products.cs file under model folder is:

public partial class Product
{

    [JsonIgnore] 
    [Key]
    public int ProductID { get; set; }
    public string ProductName { get; set; }
    public Nullable<int> SupplierID { get; set; }
    public Nullable<int> CategoryID { get; set; }
    public string QuantityPerUnit { get; set; }
    public Nullable<decimal> UnitPrice { get; set; }
    public Nullable<short> UnitsInStock { get; set; }
    public Nullable<short> UnitsOnOrder { get; set; }
    public Nullable<int> ReorderLevel { get; set; }
    public bool Discontinued { get; set; }

    public virtual Category Category { get; set; }
    public virtual Supplier Supplier { get; set; }
}

Product controller is:

public class ProductController : JsonController
{
        private readonly DBEntities _db = new DBEntities();

        public ActionResult GetProduct()
        {
            var productList = _db.Products;
            return Json(productList, JsonRequestBehavior.AllowGet);
        }
    }

Class that returns JSON and included in product controller is:

public class JsonController : Controller
{
    public new ActionResult Json(object data, JsonRequestBehavior behavior)
    {
        var jsonSerializerSetting = new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        };

        if (Request.RequestType == WebRequestMethods.Http.Get && behavior == JsonRequestBehavior.DenyGet)
        {
            throw new InvalidOperationException("GET is not permitted for this request.");
        }
        var jsonResult = new ContentResult
        {
            Content = JsonConvert.SerializeObject(data, jsonSerializerSetting),
            ContentType = "application/json"
        };
        return jsonResult;

    }
}

The productController.js file which is using AngularJS is:

myApp.controller('productController',
['$scope', 'productDataService', '$location',
    function productController($scope, productDataService) {
        $scope.products = [];
        $scope.currentPage = 1;
        $scope.pageSize = 10;
        loadProductData();

        function loadProductData() {
            productDataService.getProducts()
                .then(function () {
                    $scope.products = productDataService.products;
                },
                    function () {
                        //Error goes here...
                    })
                    .then(function () {
                        $scope.isBusy = false;
                    });
            $scope.pageChangeHandler = function (num) {
                console.log('Product page changed to ' + num);
            }
        };
    }
]);

Data service is like:

myApp.factory('productDataService', ['$http', '$q',
    function ($http, $q) {
        var _products = [];

        var _getProducts = function () {
            var deferred = $q.defer();
            var controllerQuery = "product/GetProduct";

            $http.get(controllerQuery)
                .then(function (result) {
                    // Successful
                    angular.copy(result.data, _products);
                    deferred.resolve();
                },
                    function (error) {
                        // Error
                        deferred.reject();
                    });
            return deferred.promise;
        };
        return {
            products: _products,
            getProducts: _getProducts
        };
    }
]);

Same type of code is working well for another application but I not clear why the above mentioned code is not working.

Any help will be thankfully accepted.

Thanks Partha

Ghasem
  • 14,455
  • 21
  • 138
  • 171
Partha
  • 469
  • 2
  • 14
  • 32
  • 1
    Does your `Category` contain a list of `Product` ? It says in the message 'Path '[0]*category.products'. – Khanh TO Nov 22 '15 at 08:04
  • You might have a look at my answer on **[“Self Referencing Loop Detected” exception with JSON.Net](https://stackoverflow.com/questions/40472419/self-referencing-loop-detected-exception-with-json-net/51235783#51235783)** page. – Murat Yıldız Jul 08 '18 at 20:38

3 Answers3

3

You can do this:

return new ContentResult
            {
                Content = JsonConvert.SerializeObject(data, Formatting.None, new JsonSerializerSettings {ReferenceLoopHandling = ReferenceLoopHandling.Ignore}),
                ContentType = "application/json"
            };
Mark Redman
  • 24,079
  • 20
  • 92
  • 147
1

Open WebApiConfig and register following JsonFormatter

config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling 
= Newtonsoft.Json.ReferenceLoopHandling.Ignore;
santosh singh
  • 27,666
  • 26
  • 83
  • 129
0

Yeah this is probably due to json trying to serializer your navigation objects.

public virtual Category Category { get; set; }
public virtual Supplier Supplier { get; set; }

1.Do quest test to rule this out.

2.Code up a ignore rule for them or create a DTO object for Product,

Seabizkit
  • 2,417
  • 2
  • 15
  • 32