无法使用Json序列化Web API中的响应

我正在使用ASP.NET MVC 5 Web Api。 我想咨询我所有的用户。

我写:api / users和我收到这个:

“'ObjectContent`1'types未能序列化内容types'application / json; charset = utf-8'的响应主体

在WebApiConfig中,我已经添加了这几行:

HttpConfiguration config = new HttpConfiguration(); config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType); config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; 

但仍然不起作用

我的函数返回数据是这样的:

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

当从Web Api(或任何其他Web服务)返回数据给消费者时,我强烈build议不要传回来自数据库的实体。 使用您可以控制数据看起来像而不是数据库的模型更可靠和可维护。 这样,您不必在WebApiConfig中乱搞格式化程序。 您可以创build一个具有子模型作为属性的UserModel,并摆脱返回对象中的引用循环。 这使得序列化器更加快乐。

此外,通常如果您只是在请求中指定“接受”标头,则不需要删除格式化程序或支持的媒体types。 玩弄东西有时会让事情变得更加混乱。

例:

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

如果您正在使用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模型

就那么简单!

给出正确的答案是一个方法,但是当你可以通过一个configuration设置修复它时,这是一个矫枉过正的问题。

最好在dbcontext构造函数中使用它

 public DbContext() // dbcontext constructor : base("name=ConnectionStringNameFromWebConfig") { this.Configuration.LazyLoadingEnabled = false; this.Configuration.ProxyCreationEnabled = false; } 

Asp.Net Web API错误:'ObjectContent`1'types未能序列化内容types'application / xml的响应主体; 字符集= UTF-8'

将以下代码添加到Application_Start global.asax中:

.Ignore更新到.Serialize 。 它必须工作。

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

我不喜欢这个代码:

foreach(var user in db.Users)

作为一种替代scheme,可以这样做,这对我有用:

 var listOfUsers = db.Users.Select(r => new UserModel { userModel.FirstName = r.FirstName; userModel.LastName = r.LastName; }); return listOfUsers.ToList(); 

但是,我最终使用了Lucas Roselli的解决scheme。

更新:通过返回一个匿名对象来简化:

 var listOfUsers = db.Users.Select(r => new { FirstName = r.FirstName; LastName = r.LastName; }); return listOfUsers.ToList(); 

还有这种情况会产生相同的错误:

如果返回是一个List<dynamic>到web api的方法

例:

 public HttpResponseMessage Get() { var item = new List<dynamic> { new TestClass { Name = "Ale", Age = 30 } }; return Request.CreateResponse(HttpStatusCode.OK, item); } public class TestClass { public string Name { get; set; } public int Age { get; set; } } 

因此,对于这种情况,在返回类(所有这些)中使用[KnownTypeAttribute]就像这样:

 [KnownTypeAttribute(typeof(TestClass))] public class TestClass { public string Name { get; set; } public int Age { get; set; } } 

这对我有用!

 public class UserController : ApiController { Database db = new Database(); // construction public UserController() { // Add the following code // problem will be solved db.Configuration.ProxyCreationEnabled = false; } public IEnumerable<User> GetAll() { return db.Users.ToList(); } } 

使用下面的命名空间:

using System.Web.OData;

代替 :

using System.Web.Http.OData;

它为我工作

要添加到jensendp的答案:

我会将实体传递给用户创build的模型,并使用该实体的值来设置新创build的模型中的值。 例如:

 public class UserInformation { public string Name { get; set; } public int Age { get; set; } public UserInformation(UserEntity user) { this.Name = user.name; this.Age = user.age; } } 

然后将您的返回types更改为: IEnumerable<UserInformation>

使用AutoMapper …

 public IEnumerable<User> GetAll() { using (Database db = new Database()) { var users = AutoMapper.Mapper.DynamicMap<List<User>>(db.Users); return users; } } 

我个人的最爱:只需将下面的代码添加到App_Start/WebApiConfig.cs 。 这将默认返回json而不是XML,并且还会防止出现错误。 不需要编辑Global.asax来移除XmlFormatter

“ObjectContent`1”types未能序列化内容types为“application / xml; 字符集= utf-8的

 config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html")); 

另一个我收到这个错误的情况是当我的数据库查询返回一个空值,但我的用户/视图模型types被设置为不可空。 例如,将我的UserModel字段从int更改为int? 解决。

解决scheme,为我工作:

  1. 使用[DataContract]为每个属性的[DataMember]属性进行序列化。这足以获得Json结果(例如来自fiddler)。

  2. 要获得xml序列化,请在Global.asax中写入以下代码:

    var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter; xml.UseXmlSerializer = true;

  3. 阅读这篇文章,它帮助我理解序列化: https : //www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization