未能在 Web API 中序列化响应

我正在开发 ASP.NET MVC web API,我有一个错误:

‘ ObjectContent‘1’类型未能序列化内容类型‘ application/xml; charset = utf-8’的响应正文。

我的控制器是:

public Employee GetEmployees()
{
Employee employees = db.Employees.First();
return employees;
}

为什么我会得到这个错误?

96077 次浏览

in your global.asax file, in the Application_start() method add this line:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;

I hope that helps you!

hmmm, Following may help.

I was getting the same exception, and in my case I was passing the actual poco entity created for entity code first. Since, it contains relation with other entities, I just created the viewmapper/dto entity on top of it to return.

It works fine now.

Poco Entity:

public class Tag
{
public int Id{get;set;}
public string Title{get;set;}
public IList<Location> Locations{get;set;}
}

ViewMapper/Dto

public class TagResultsViewMapper
{
public int Id{get;set;}
public string Title{get;set;}
//just remove the following relationship
//public IList<Location> Locations{get;set;}
}

Put this in constructor. Hope this solve the problem:

    public MyController()
{


db.Configuration.ProxyCreationEnabled = false;
}

I found two solutions to this. The first and easiest to implement is to change any IEnumerables, ICollections to a type of List. The WebAPI can serialize this objects, it however cannot serialize interface types.

public class Store
{


[StringLength(5)]
public string Zip5 { get; set; }


public virtual List<StoreReport> StoreReports { get; set; }  //use a list here
}

The other option is to not use the native JSON serializer and run this override in the Register method of the WebApi Config:

        var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);

I got the same problem. And I solved it. I put the default constructor to the DTO class.

Ex:

public class User
{
public User()
{
}
}

Hope it work with you!

please check the web api documentation for this problem, Handling Circular Object References

Regards

but if you found this problem with other entities/classes, you have to create a new DTO for each class, and if you have a lot of them, you can find a problem, also I think that create a DTO only for solving this problem is no the best way...

Did you try this?

var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling =
Newtonsoft.Json.PreserveReferencesHandling.All;

Regards

Solution is simple.

After LINQ query add .ToList() (or ToDictionary if need).

It will do eager loading than lazy loading of the data

For me this was a problem with circular referencing.

The accepted answer did not work for me because it only changes the behaviour of the JSON formatter, but I was getting XML when I called the service from the browser.

To fix this, I switched off XML and forced only JSON to be returned.

In the Global.asax file, put the following lines at the top of your Application_Start method:

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

Now only JSON results will be returned. If you need XML results, you will need to find a different solution.

** this bug occur when calling from request web api/wcf/... from client side, but as side effect, you will need to include depending relations by include keyword. **

public CustomerPortalContext()
: base("Name=CustomerPortalContext")
{
base.Configuration.ProxyCreationEnabled = false;
}

Your question is quite similar to mine. You must not return data from database directly. For this, you must create Model and associate data you want show.

In my example, There are data about User that Json couldn't serialize, I had create a userModel and, in my API, I return userModel instead User from database.

The logic of convert or associate data between User and UserModel must be in API.

Failed to serialize the response in Web API with Json

If you use web api with Entity Framework, a solution can be Failed to serialize the response in Web API with Json

Basically, you need to create a model corresponding to each EF model, this removes dependencies between classes and allow easy serialization.

Code: (taken from the referenced link)

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;
listOfUsers.Add(userModel);
}
IEnumerable<UserModel> users = listOfUsers;


return users;
}
}

If you are working with EF, besides adding the code below on Global.asax

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

Dont`t forget to import

using System.Data.Entity;

Then you can return your own EF Models

Default Entity 6 use XML to apis, in your project, find the file "Global.asax" File and add this line:

GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);

This line remove the XML Formatter.

This was the specific error I was getting back from my odata Web API call:

The 'ObjectContent`1' type failed to serialize the response
body for content type 'application/json; odata.metadata=minimal'.

I finally figured out that my dbContext class had a poorly formatted table name being assigned in onModelCreating.. so the SqlClient was dying looking for a table that didn't exist in my db!!