无法使用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,为我工作:
-
使用[DataContract]为每个属性的[DataMember]属性进行序列化。这足以获得Json结果(例如来自fiddler)。
-
要获得xml序列化,请在Global.asax中写入以下代码:
var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter; xml.UseXmlSerializer = true;
- 阅读这篇文章,它帮助我理解序列化: https : //www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization
- Json.Net中的PreserveReferencesHandling和ReferenceLoopHandling有什么区别?
- System.Diagnostics.Process.Start不能从IIS工作
- ASP.NET Web窗体是否阻止双击提交?
- 在asp.net的样式表path中使用斜线(/)和波浪线斜线(〜/)
- 在razor页面中检查login用户angular色
- .NET 3.5中有一个GUID.TryParse()吗?
- 如何为所有视图设置ViewBag属性而不使用控制器的基类?
- 使用Twitter Bootstrap在@ html.actionlink中显示html
- 我如何解决Kerberos双跳问题?