簡體   English   中英

從Web API返回Entity Framework類會引發“未能序列化內容類型的響應正文”異常

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM