CampDev CampDev - 1 year ago 175
C# Question

Failed to serialize the response in Web API with Json

I am working with ASP.NET MVC 5 Web Api. I want consult all my users.

I write: api/users and I receipt this:

"The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'"

In WebApiConfig, already I added this lines:

HttpConfiguration config = new HttpConfiguration();
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;

But still doesn't work

My function for return data is this:

public IEnumerable<User> GetAll()
using (Database db = new Database())
return db.Users.ToList();

The solution was

Create a UserModel

public class UserModel
public string FirstName { get; set; }
public string LastName { get; set; }

Change my method GetAll()

public IEnumerable<UserModel> GetAll()
using (Database db = new Database ())
List<UserModel> listOfUsers = new List<UserModel>();
UserModel userModel = new UserModel();
foreach(var user in db.Users)
userModel.FirstName = user.FirstName;
userModel.LastName = user.LastName;
IEnumerable<UserModel> users = listOfUsers;

return users;

Thank you jensendp and mckeejm for your explanations.

Answer Source

When it comes to returning data back to the consumer from Web Api (or any other web service for that matter), I highly recommend not passing back entities that come from a database. It is much more reliable and maintainable to use Models in which you have control of what the data looks like and not the database. That way you don't have to mess around with the formatters so much in the WebApiConfig. You can just create a UserModel that has child Models as properties and get rid of the reference loops in the return objects. That makes the serializer much happier.

Also, it isn't necessary to remove formatters or supported media types typically if you are just specifying the "Accepts" header in the request. Playing around with that stuff can sometimes make things more confusing.


public class UserModel {
    public string Name {get;set;}
    public string Age {get;set;}
    // Other properties here that do not reference another UserModel class.