簡體   English   中英

C# api 給出錯誤“'ObjectContent`1' 類型未能序列化內容類型'application/xml; charset=utf-8' 的響應主體。”

[英]C# api gives error "The 'ObjectContent`1' type failed to serialize the response body for content type 'application/xml; charset=utf-8'."

我完全按照本教程進行操作,但是當我運行代碼時,收到此錯誤消息。

 <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.Player_B392F8ACFF7986B6E577FBE0EA4EC58EB44F1C4138CB96BE272A810004835B21' with data contract name 'Player_B392F8ACFF7986B6E577FBE0EA4EC58EB44F1C4138CB96BE272A810004835B21: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.SerializeWithXsiTypeAtTopLevel(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle originalDeclaredTypeHandle, Type graphType) 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.Web.Http.WebHost.HttpControllerHandler.<WriteBufferedResponseContentAsync>d__22.MoveNext()
</StackTrace>
</InnerException>
</Error>

我不明白我的代碼在哪里失敗,因為它與教程相同。

例如控制器看起來像這樣:

 using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; using UEFA_APIDataAcces; namespace UEFA_API.Controllers { [RoutePrefix("api/Match")] public class MatchController : ApiController { [Route("")] public IEnumerable<Match> Get() { using(UEFAEntities entities = new UEFAEntities()) { return entities.Match.ToList(); } } [Route("{id:int}")] public Match Get(int id) { using (UEFAEntities entities = new UEFAEntities()) { return entities.Match.FirstOrDefault(e => e.ID == id); } } } }

我也看到了這個解決方案,但這對我不起作用。 我仍然收到錯誤消息。

歡迎任何幫助/提示。

先感謝您。

較早的實體框架版本(即 Core 2.1 之前的版本)在知道可以延遲加載數據時默認為數據模型使用代理類。 例如,如果你有一個類Parent和一個類Children的集合,默認情況下,當你通過這樣的東西加載Parent對象時

var parent = entities.Parents.FirstOrDefault(p=>p.Id==pid)

然后 EF 將 - 默認情況下 - 在您第一次嘗試引用它們之前不會加載相關的 childed

例如只在你寫的地方

var child = parent.Children.Where(c=>c.SomeProperty==true)

將發送一個新的 SQL 查詢來獲取子項。 這是通過在運行時為Parent對象生成的(對您透明的)代理類​​來啟用的,它檢測到您想要訪問Children集合並發出 SQL,執行映射等。

不幸的是,由於各種原因,這些 Proxy 類並不能很好地(如果有的話)進行序列化。 因此,您收到的錯誤消息。 EF Core 2.1 更改了一些內容,因此默認情況下延遲加載處於關閉狀態,您必須啟用它。 但是,如果您使用任何早期版本(包括非核心 EF),則默認情況下它處於啟用狀態。

這也可以解釋為什么您在沒有外鍵的情況下創建新數據庫有效,因為 EF 將無法推斷與子對象的關系,因此它不會創建代理,這意味着您正在處理的類現在就是我們所說的POCO (普通的舊 CLR 對象)。 但是您正在剝奪自己(和 EF)在關系數據庫中擁有相關對象的能力,從長遠來看這可能不是一件好事:)

就更好的解決方案而言,有幾個選項可以關閉代理創建,或在序列化之前拉取整個對象圖:

var parent = entities.Parents.Include("Children").FirstOrDefault(p=>SomeCondition);

這將加載整個Parent實體及其所有的Children在一氣呵成,避免這個問題為好; 然而,這並不總是理想的,因為您實際上可能並不每次都想要Children實體。

但更好的是,不要直接公開您的 EF 模型,而是使用映射到 DTO(數據傳輸對象)

我推薦 DTO; 使用 DTO 的最大優點是您不需要將您的 EF 實體暴露給外界,因為例如其中可能有一些與消費者無關的部分,或者您可能想要對某些子項進行聚合歸還前收集等。

這里有一個很棒的指南可以更深入地討論這些主題。

顯然這是我在數據庫中的外鍵的問題。 我創建了一個具有相同數據但沒有外鍵的新數據庫,現在我的應用程序運行良好。

我希望我也可以幫助其他人回答這個問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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