内容协商在 Web 中不起作用 Api
Content Negotiation is not working in Web Api
我有以下代码来演示网络中的内容协商api。但它抛出异常。
IEnumerable<Person> personList = _repository.GetAllPerson();
if (personList == null)
throw new HttpResponseException(HttpStatusCode.NotFound);
IContentNegotiator negotiator = this.Configuration.Services.GetContentNegotiator();
ContentNegotiationResult result = negotiator.Negotiate(typeof(Person), this.Request, this.Configuration.Formatters);
if (result == null)
{
var response = new HttpResponseMessage(HttpStatusCode.NotAcceptable);
throw new HttpResponseException(response);
}
HttpResponseMessage responseMsg = new HttpResponseMessage()
{
Content = new ObjectContent<IEnumerable<Person>>(
personList, // What we are serializing
result.Formatter, // The media formatter
result.MediaType.MediaType // The MIME type
)
};
return Request.CreateResponse(HttpStatusCode.OK, responseMsg);
例外情况是:
The 'ObjectContent`1' type failed to serialize the response body for
content type 'application/json; charset=utf-8'.
请给我一个建议。我的 WebApiConfig.cs 代码是:
// Web API configuration and services
//XML output
var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter;
xml.UseXmlSerializer = true;
//Json output
var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.UseDataContractJsonSerializer = true;
json.SerializerSettings.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat;
json.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;
json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.All;
// Remove the XML formatter
//config.Formatters.Remove(config.Formatters.XmlFormatter);
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
这是关于序列化,而不是内容协商。我猜您正在查询数据库并使用 Entity Framework 从存储库中取回 IQueryable
结果?尝试几个步骤:
改变这个:
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.All;
对此:
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Ignore;
您可能还需要在 EF 配置中禁用延迟加载,具体取决于 Person
的形状:
public MyEntitiesContext() : base("name=MyEntitiesContext", "MyEntitiesContext")
{
this.Configuration.LazyLoadingEnabled = false;
this.Configuration.ProxyCreationEnabled = false;
}
另一种选择(对于非平凡的解决方案可能更好的策略是 return 来自网络的不同 class(视图模型、dto,甚至是投影)api而不是 returning 您的 EF 实体。
最后一行有问题。
return Request.CreateResponse(HttpStatusCode.OK, responseMsg);
答案是:
return new HttpResponseMessage()
{
Content = new ObjectContent<IList<PersonModel>>(
personModelList, // What we are serializing
result.Formatter, // The media formatter
result.MediaType.MediaType // The MIME type
),
StatusCode = HttpStatusCode.OK
};
我有以下代码来演示网络中的内容协商api。但它抛出异常。
IEnumerable<Person> personList = _repository.GetAllPerson();
if (personList == null)
throw new HttpResponseException(HttpStatusCode.NotFound);
IContentNegotiator negotiator = this.Configuration.Services.GetContentNegotiator();
ContentNegotiationResult result = negotiator.Negotiate(typeof(Person), this.Request, this.Configuration.Formatters);
if (result == null)
{
var response = new HttpResponseMessage(HttpStatusCode.NotAcceptable);
throw new HttpResponseException(response);
}
HttpResponseMessage responseMsg = new HttpResponseMessage()
{
Content = new ObjectContent<IEnumerable<Person>>(
personList, // What we are serializing
result.Formatter, // The media formatter
result.MediaType.MediaType // The MIME type
)
};
return Request.CreateResponse(HttpStatusCode.OK, responseMsg);
例外情况是:
The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'.
请给我一个建议。我的 WebApiConfig.cs 代码是:
// Web API configuration and services
//XML output
var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter;
xml.UseXmlSerializer = true;
//Json output
var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.UseDataContractJsonSerializer = true;
json.SerializerSettings.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat;
json.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;
json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.All;
// Remove the XML formatter
//config.Formatters.Remove(config.Formatters.XmlFormatter);
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
这是关于序列化,而不是内容协商。我猜您正在查询数据库并使用 Entity Framework 从存储库中取回 IQueryable
结果?尝试几个步骤:
改变这个:
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.All;
对此:
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Ignore;
您可能还需要在 EF 配置中禁用延迟加载,具体取决于 Person
的形状:
public MyEntitiesContext() : base("name=MyEntitiesContext", "MyEntitiesContext")
{
this.Configuration.LazyLoadingEnabled = false;
this.Configuration.ProxyCreationEnabled = false;
}
另一种选择(对于非平凡的解决方案可能更好的策略是 return 来自网络的不同 class(视图模型、dto,甚至是投影)api而不是 returning 您的 EF 实体。
最后一行有问题。
return Request.CreateResponse(HttpStatusCode.OK, responseMsg);
答案是:
return new HttpResponseMessage()
{
Content = new ObjectContent<IList<PersonModel>>(
personModelList, // What we are serializing
result.Formatter, // The media formatter
result.MediaType.MediaType // The MIME type
),
StatusCode = HttpStatusCode.OK
};