2012-09-28 42 views
7

我使用流利的API製作了實體框架代碼。實體框架在我的WebAPI Mvc4解決方案中無法使用

我有一個Web API控制器:

public class NewsController : ApiController 
{ 
    private TrafficTheoryContext db = new TrafficTheoryContext(); 

    // GET api/News 
    public IEnumerable<News> GetNews() 
    { 
     //return new List<News> { 
     // new News{ Title = "Featuring Azure ACS Authentication", Subtile="Hello "}}; 
     return db.News.AsEnumerable(); 
    } 
} 

,如果我做一個GET請求,我得到一個錯誤:

此XML文件沒有出現有任何相關的樣式信息。文檔樹如下所示。

<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.News_786DE29B12691F869E9C9DF523A808EABE06546C3FCE3354F77875B83B9EB51C' with data contract name 'News_786DE29B12691F869E9C9DF523A808EABE06546C3FCE3354F77875B83B9EB51C:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies' is not expected. Consider using a DataContractResolver 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 DataContractSerializer. 
</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 WriteArrayOfNewsToXml(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.<>c__DisplayClass7.<WriteToStreamAsync>b__6() at System.Threading.Tasks.TaskHelpers.RunSynchronously(Action action, CancellationToken token) 
</StackTrace> 
</InnerException> 
</Error> 

如果我只是返回一個新聞列表它工作罰款。我注意到這些clases附加了某​​種我不知道是什麼的名字?

如何讓webapi工作?

回答

4

我相信你會得到這個異常,因爲你的實體生成的動態代理。如果查看異常消息,則實際上不會序列化新聞類型,而是System.Data.Entity.DynamicProxies.News_786DE29B12691F869E9C9DF523A808EABE06546C3FCE3354F77875B83B9EB51C類型。這種類型是由Entity Framework爲您創建的,以支持延遲加載。你可以在這裏找到更多關於動態代理的細節:http://msdn.microsoft.com/en-US/data/jj592886。 我不知道的WebAPI非常好,但例外實際上說的有什麼需要做:

類型「System.Data.Entity.DynamicProxies.News_786DE29B12691F869E9C9DF523A808EABE06546C3FCE3354F77875B83B9EB51C」數據合同名稱 「News_786DE29B12691F869E9C9DF523A808EABE06546C3FCE3354F77875B83B9EB51C:HTTP://模式。 datacontract.org/2004/07/System.Data.Entity.DynamicProxies' 不是預期的。 考慮使用DataContractResolver或將任何不知道的類型靜態添加到已知類型的列表中 - 例如,通過使用KnownTypeAttribute屬性或將它們添加到傳遞給DataContractSerializer的已知類型的列表。

由於該類型是自動創建的,因此您無法放置該屬性。因此,我將重點討論「考慮使用DataContractResolver」和「將它們添加到傳遞給DataContractSerializer的已知類型列表」部分。

Btw你用什麼版本的EF?我想我之前看到過這個問題,並且在EF5 RTM中修復了這個問題。

+0

我使用:\ EntityFramework.5.0.0 \ LIB \ net40 \ EntityFramework.dll和禁用是懶惰和PROXI解決了問題,但林不知道如果多數民衆贊成一個好主意? –

+0

我不知道DataContractResolver是什麼,將谷歌它。 –

+0

重新禁用延遲加載(或代理創建) - 這取決於您的應用程序是否正在使用它。如果是,那麼你的應用程序會崩潰,如果你期望導航屬性自動加載,它不會(因爲代理創建被禁用) – Pawel

0

而不是.AsEnumerable,使用.ToList()。我也很好奇你是如何創建和銷燬數據上下文的。

+0

我只是把私人TrafficTheoryContext db = new TrafficTheoryContext();在控制器類中。 .AsEnumerable工作正常 - 我發現禁用lazyloading和代理它的作品。這是一個壞主意嗎? –

+1

@ s093294 - 好吧,通過禁用它,你會削弱EF功能的一部分。這意味着你需要顯式地包含()所有你想使用的表。有些人喜歡那樣,有些人則不喜歡。另外,沒有代理生成意味着沒有更改跟蹤,並且更改跟蹤對於保持上下文的狀態同步非常重要。如果您禁用了代理創建,那麼您必須非常小心如何插入,更新或刪除記錄。 –

+0

好的,使用toList()也沒有工作,它只是一個代理列表。 –

4

我在我的Mcv5項目中也面臨同樣的問題,當我禁用代理創建時,每件事情都像魅力一樣工作。我希望它也能幫助你。

DbContext.Configuration.ProxyCreationEnabled = false; 
相關問題