1
public partial class User
{
    public System.Guid UserId { get; set; }
    public Nullable<System.Guid> RoleId { get; set; }
    public Nullable<long> MembershipNo { get; set; }
    public string Username { get; set; }
    public string Password { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Gender { get; set; }
    public string Emaiil { get; set; }
    public Nullable<decimal> MobileNo { get; set; }
    public string Description { get; set; }
    public Nullable<System.Guid> ModifiedBy { get; set; }
    public Nullable<System.DateTime> ModifiedDate { get; set; }
    public virtual Role Role { get; set; }
 }

This is my table in DB named Users which is associated with Roles table of DB (as you can see last virtual row at the end above)

Now My problem is simple. I'm using angulars $http.get() method to call my Web Api in MVC 4. When i call it, it gets connected and fetches desired record but it doesn't throw proper result back to .js file or controller. At .js side I run into error. Every time, it executes .error(jsonResult,config,header,status) .

When I jump on to JsonResult, it shows me below error.

    Object
    ExceptionMessage: "The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'."
    ExceptionType: "System.InvalidOperationException"
    InnerException: Object
    ExceptionMessage: "Self referencing loop detected for property 'Role' with type
    'System.Data.Entity.DynamicProxies.Role_82CA96EA045B1EB47E58B8FFD4472D86502EEA79837B4AE3AD705442F6236E58'. 
    Path 'Role.Users[0]'."
    ExceptionType: "Newtonsoft.Json.JsonSerializationException"
    Message: "An error has occurred."

I don't know what's wrong here. Is it json parsing error or something? if so, I've heard and read the articles that webapi in .net handles or throws json itself.

My call happens through

 $http.get(apiUrl).success(function (jsonResult, header, config, status) {

    debugger;
    var number = parseInt(jsonResult.membershipNo) + 1;

    $scope.membershipNo = "M" + number;

})
.error(function (jsonResult, header, config, status) {
    debugger;
    toastr.error('Something went wrong ! Contact Administrator!!!');
});

Edited:

One more thing to mention, .CS side when I fetch single cell value (from DB/table) , it gets returned back to .success() call but when i fetch particular row or all rows, it gets returned to .error() call. I'm using entity frameworkd 6.1.1. and above class is generated by EF-6.1.1.


public partial class Role
{
public Role()
{
    this.Permissions = new List<Permission>();
    this.Users = new List<User>();
}

public System.Guid RoleId { get; set; }
public string RoleName { get; set; }
public string Description { get; set; }
public Nullable<System.Guid> ModifiedBy { get; set; }
public Nullable<System.DateTime> ModifiedDate { get; set; }
public virtual ICollection<Permission> Permissions { get; set; }
public virtual ICollection<User> Users { get; set; }
}
micronyks
  • 54,797
  • 15
  • 112
  • 146
  • it looks like a cyclic references problem when asp.net web api is trying to serialize your objects to JSON as stated in the error `Self referencing loop detected for property 'Role'` – Khanh TO Jul 20 '14 at 08:44
  • Hmm... what should be the solution? – micronyks Jul 20 '14 at 08:45
  • usually, when we serialize objects to JSON, we should serialize view Model object (DTO) instead of your domain model. – Khanh TO Jul 20 '14 at 08:46
  • try converting your domain model object to a `flattened` view model object (DTO): http://stackoverflow.com/questions/4061440/asp-net-mvc-model-vs-viewmodel – Khanh TO Jul 20 '14 at 08:47
  • What is your Role class. If you have User property in Role class, exclude it from serialization or use a view model instead of domain model as Khanh TO sad. – Alborz Jul 20 '14 at 08:51
  • okay let me show you role class generated by EF. please refer to edited section now. – micronyks Jul 20 '14 at 08:56

2 Answers2

1

it sounds like: the problem is that EF is using lazy loading that is not materialized in time of constructing this, on role. EF from early version has switched lazy loading on by default.

Suggested solution Create subset of you user class, with the parts that you really need. => Its bad practise to fetch too much data that you are not gonna need.

cpoDesign
  • 8,953
  • 13
  • 62
  • 106
  • thanks for the suggestions. I'd keep all things in mind. Yes its good practice to create custom model but i was curious to know about what was wrong... – micronyks Jul 20 '14 at 11:35
1

Hi you can solve that in 2 easy steps

First Step: Create globalConfig class where you can set ignoring ReferenceLoopHandling (http://james.newtonking.com/json/help/index.html?topic=html/SerializationSettings.htm) and if you crating js app you can set as well to remove xml formaters and always get return from Webapi as JSON string is usefull for debugging. So in your app_start folder add class GlobalConfig like below:

public class GlobalConfig
  {
                    public static void CustomizeConfig(HttpConfiguration config)
                    {
                        // Remove Xml formatters. This means when we visit an endpoint from a browser,
                        // Instead of returning Xml, it will return Json.
                        //that is optional

                        config.Formatters.Remove(config.Formatters.XmlFormatter);   
                       GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = 
    Newtonsoft.Json.ReferenceLoopHandling.Ignore;

                    }
}

Second Step: In Global.asax set your custom configuration to do that please add code below to method Application_Start():

 GlobalConfig.CustomizeConfig(GlobalConfiguration.Configuration);
sylwester
  • 16,498
  • 1
  • 25
  • 33
  • This solution works! @Sylwester would you please explain what is this? I'd like to add into my knowledge.I've almost understood. still would like to gain more from your end. – micronyks Jul 20 '14 at 11:25
  • @all...I wonder what would happen when I want to add 'user'-model (created at js side) with required fields and throw it to .CS. would it accept my user-model as i won't be adding 'last virtual key' named 'Role'. (will it accept my user-model .CS side with ---public dynamic Post(User user)????????????) – micronyks Jul 20 '14 at 11:38
  • I will do when I back home – sylwester Jul 20 '14 at 11:46