无法在Web API中序列化响应

时间:2012-09-28 13:53:53

标签: c# serialization asp.net-web-api

我正在使用ASP.NET MVC Web API,我遇到了这个错误:

  

'ObjectContent`1'类型无法序列化内容类型'application / xml的响应主体;字符集= UTF-8' 。

我的控制器是:

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

为什么我收到此错误?

15 个答案:

答案 0 :(得分:117)

对我来说这是循环引用的问题。

接受的答案对我不起作用,因为它只会改变JSON格式化程序的行为,但是当我从浏览器调用服务时,我得到了XML。

为了解决这个问题,我关闭了XML并强制只返回JSON。

在Global.asax文件中,将以下行放在Application_Start方法的顶部:

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

现在只返回JSON结果。如果您需要XML结果,则需要找到不同的解决方案。

答案 1 :(得分:43)

在你的global.asax文件中,在Application_start()方法中添加以下行:

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

我希望能帮到你!

答案 2 :(得分:29)

我遇到了同样的问题。我解决了它。我把默认构造函数放到DTO类中。

例如:

public class User
{
    public User()
    {
    }
}

希望它与你合作!

答案 3 :(得分:21)

将它放在构造函数中。希望这能解决问题:

    public MyController()
    {

        db.Configuration.ProxyCreationEnabled = false;
    }

答案 4 :(得分:16)

我找到了两个解决方案。第一个也是最容易实现的是将任何IEnumerables,ICollections更改为List类型。 WebAPI可以序列化这些对象,但是它不能序列化接口类型。

public class Store
{

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

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

另一个选择是不使用本机JSON序列化程序并在WebApi配置的Register方法中运行此覆盖:

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

答案 5 :(得分:7)

解决方案很简单。

在LINQ查询之后添加.ToList()(或ToDictionary,如果需要)。

它会比延迟加载数据做出急切的加载

答案 6 :(得分:4)

** 从客户端请求web api / wcf / ...调用时会出现此错误,但作为副作用,您需要通过include关键字包含依赖关系。 **

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

答案 7 :(得分:4)

如果您正在使用EF,除了在Global.asax上添加以下代码

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

不要忘记导入

using System.Data.Entity;

然后您可以返回自己的EF模型

答案 8 :(得分:3)

请查看此问题的网络API文档Handling Circular Object References

此致

答案 9 :(得分:3)

如果您使用带有Entity Framework的web api,可以使用解决方案 Failed to serialize the response in Web API with Json

基本上,您需要创建与每个EF模型相对应的模型,这样可以消除类之间的依赖关系并允许轻松序列化。

代码:(取自引用的链接)

创建UserModel

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

更改我的方法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;
    }
}

答案 10 :(得分:1)

嗯,以下可能有所帮助。

我得到了同样的例外,在我的情况下,我首先传递了为实体代码创建的实际poco实体。因为,它包含与其他实体的关系,我只是在它上面创建了viewmapper / dto实体来返回。

现在工作正常。

Poco实体:

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;}
}

答案 11 :(得分:1)

但如果你发现其他实体/类有这个问题,你必须为每个类创建一个新的DTO,如果你有很多,你可以找到一个问题,我认为只创建一个DTO解决这个问题不是最好的方法......

你试过这个吗?

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

此致

答案 12 :(得分:1)

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

from tkinter import *
from tkinter import ttk

class App(Frame):
    def __init__(self, master):
        ttk.Frame.__init__(self, master, padding='20')
        self.grid()
        self.create_checkbox()
        self.create_entry()

    def create_checkbox(self):
        self.limit = BooleanVar()
        Checkbutton(self,
                    text='Limit length',
                    variable= self.limit,
                    command= self.state_update,
                    ).grid(row=1, column=1, sticky=W)

    def create_entry(self):
        self.entry_low = StringVar()
        Entry(self,
              width=6,
              textvariable=self.entry_low,
              state='disabled',
              ).grid(row=1, column=2, sticky=W)


    def state_update(self):
        self.entry_low.config(state="normal")  #THIS OBVIOUSLY DOES NOT WORK

root = Tk()
root.title("Lottery")
app = App(root)
root.mainloop()

This line remove the XML Formatter.

答案 13 :(得分:0)

你的问题与我的问题很相似。您不能直接从数据库返回数据。为此,您必须创建模型并关联您想要显示的数据。

在我的例子中,有关于用户的数据,Json无法序列化,我创建了一个userModel,在我的API中,我从数据库返回userModel而不是User。

在User和UserModel之间转换或关联数据的逻辑必须在API中。

Failed to serialize the response in Web API with Json

答案 14 :(得分:0)

这是我从odata Web API调用中得到的具体错误:

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

我终于发现我的dbContext类在onModelCreating中分配了格式不正确的表名 ..所以SqlClient正在寻找一个在我的数据库中不存在的 !!