![](/img/trans.png)
[英]Web API controller fails with The 'ObjectContent`1' type failed to serialize the response body
[英]Returning Entity Framework class from Web API throws “failed to serialize the response body for content type” exception
我面臨以下問題,我有一個對象模型BlogEntry:
public class BlogEntry
{
public int Id { get; set; }
[Required]
public DateTime BlogEntryDate { get; set; }
[Required]
public string BlogEntryTitle { get; set; }
[Required]
public string BlogEntrySummary { get; set; }
[Required]
public string BlogEntryContent { get; set; }
[Required]
public string BlogEntryPublishedBy { get; set; }
[Required]
public bool BlogEntryPublished { get; set; }
public int BlogCategoryId { get; set; }
public virtual BlogCategory BlogCategory { get; set; }
}
我用模型生成了控制器,並且有了方法:
// GET: api/BlogEntries
[AllowAnonymous]
public IQueryable<BlogEntry> GetBlogEntries()
{
return db.BlogEntries;
}
問題是,當我測試該方法時,序列化有錯誤:
'ObjectContent`1'類型未能序列化內容類型'application / xml的響應主體; charset = utf-8'
我試圖在WebAPIConfig.cs中使用以下代碼進行修復:
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
config.Formatters.JsonFormatter
.SerializerSettings
.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
實際上,這可以在本地解決問題,但是當我將應用程序發布到Azure時,始終向我提供錯誤代碼500。注意:我調試了方法,並且代碼中沒有問題,實際上非常簡單。
有什么想法嗎
<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
The 'ObjectContent`1' type failed to serialize the response body for content type 'application/xml; charset=utf-8'.
</ExceptionMessage>
<ExceptionType>System.InvalidOperationException</ExceptionType>
<StackTrace/>
<InnerException>
<Message>An error has occurred.</Message>
<ExceptionMessage>
Type 'System.Data.Entity.DynamicProxies.BlogEntry_2BC5105C1EBC22432CBA0E820087939FDB4E152CC4026BA3BC6DDDD9C1156A4D' with data contract name 'BlogEntry_2BC5105C1EBC22432CBA0E820087939FDB4E152CC4026BA3BC6DDDD9C1156A4D:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies' is not expected. Consider using a DataContractResolver if you are using DataContractSerializer or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to the serializer.
</ExceptionMessage>
<ExceptionType>
System.Runtime.Serialization.SerializationException
</ExceptionType>
<StackTrace>
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeAndVerifyType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, Boolean verifyKnownType, RuntimeTypeHandle declaredTypeHandle, Type declaredType) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithXsiType(XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle objectTypeHandle, Type objectType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle, Type declaredType) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle) at WriteArrayOfBlogEntryToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , CollectionDataContract ) at System.Runtime.Serialization.CollectionDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle) at System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.DataContractSerializer.WriteObject(XmlWriter writer, Object graph) at System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content) at System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at System.Web.Http.WebHost.HttpControllerHandler.<WriteBufferedResponseContentAsync>d__1b.MoveNext()
</StackTrace>
</InnerException>
</Error>
問題是它也在嘗試序列化BlogCategory 。
public virtual BlogCategory BlogCategory { get; set; }
首先,從Web API (或與此相關的任何API)返回Entity類不是一個好習慣。 通常,我們將Entity映射到DTO (數據傳輸對象)中。
測試最簡單的方法是創建DTO類-
public class BlogEntryModel
{
public int Id { get; set; }
public DateTime BlogEntryDate { get; set; }
public string BlogEntryTitle { get; set; }
public string BlogEntrySummary { get; set; }
public string BlogEntryContent { get; set; }
public string BlogEntryPublishedBy { get; set; }
public bool BlogEntryPublished { get; set; }
public int BlogCategoryId { get; set; }
}
然后返回它而不是BlogEntry。
return db.BlogEntries
.Select(x => new BlogEntryModel
{
Id = x.Id,
...
})
.ToList();
正確的方法是使用AutoMapper和存儲庫模式,但是這超出了原始問題的范圍,我不想從OP旁聽。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.