Mohit Shah
Mohit Shah

Reputation: 862

Serialization Error ASP.NET Web API

I have two Model Classes State and City

public partial class State
{
    public State()
    {
        this.City = new HashSet<City>();
    }

    public int State_Id { get; set; }
    public string State_Name { get; set; }
    public virtual ICollection<City> City { get; set; }
}

public partial class City
{
    public int City_Id { get; set; }
    public string City_Name { get; set; }
    public int State_Id { get; set; }

    public virtual State State { get; set; }
}

My DTO_State Class Is as follows which is for State data transfer objects

public class DTO_State
{
    public int State_Id { get; set; }
    public string State_Name { get; set; }
    public ICollection<int> City_Id { get; set; } 
}

In the StateController My Get action method is as follows

This code inside gives me serialization error

    public IQueryable<DTO_State> GetState()
    {   
        var dstates = from S in db.State select new DTO_State()
        {
            State_Id = S.State_Id,
            State_Name=S.State_Name,
            City_Id = S.City.Select(x => x.City_Id).ToList()
       };
        return dstates.AsQueryable();
    }

But If I replace it with this then I get correct data in browser

    public IQueryable<DTO_State> GetState()
    {
        List<DTO_State> dstates = new List<DTO_State>();
        IQueryable<State> states = db.State;

        foreach (State S in states)
        {
            DTO_State dstate = new DTO_State();
            dstate.State_Id = S.State_Id;
            dstate.State_Name = S.State_Name;
            dstate.City_Id = S.City.Select(x => x.City_Id).ToList();
            dstates.Add(dstate);
        }
        return dstates.AsQueryable();
    }

Edit: In the following screenshots State,City,DTO_State are same as New_State,New_City and DTO_New_State so please do not get confused

Here I will show what happens in debug view for first erroneous code

When cursor is over states this happens

When cursor over dstates this happens

enter image description here

Now even if multithreading is there dstates should have been evaluated by know but it is not

Now for the correct code Screenshots are as follows Here from debugging I observe that as the LINQ Query gets executed on each iteration on pointing cursor over the states variable its count increases by one so whenever the next value of states variable is required it is obtained by some multithreading mechanism (There are total 5 states)

enter image description here

In the next picture at this point in debugging states and dstates are both populated

enter image description here

Correct Output in Browser

enter image description here

So in a nutshell I don't know if LINQ Query is not supporting multithreading or something because WebAPI internally does multithreading so please help me out here

Upvotes: 1

Views: 478

Answers (1)

Trey Mack
Trey Mack

Reputation: 4725

Use .AsEnumerable() or .ToList() instead of .AsQueryable(). Or in between your LINQ query and .AsQueryable() if you can't control the interface you're implementing with

public IQueryable<DTO_State> GetState()

What's the difference(s) between .ToList(), .AsEnumerable(), AsQueryable()? will help explain the mechanics.

AsEnumerable is frequently used to switch from any IQueryable implementation to LINQ to objects (L2O)

Update:

After reviewing the error message, looks like a bug in EF. Exception on Inner LINQ query when calling ToList()

You'll have to change ICollection of Cities to IEnumerable.

Upvotes: 1

Related Questions