【问题标题】:Entity Framework not serviceable in my WebAPI Mvc4 solution实体框架在我的 WebAPI Mvc4 解决方案中不可用
【发布时间】:2014-11-13 17:27:32
【问题描述】:

我已经使用 fluent api 制作了实体框架代码。

我有一个 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>

如果我只是返回一个新闻列表,它可以正常工作。我注意到这些类附加了某种我不知道是什么的名称?

如何让 webapi 工作?

【问题讨论】:

    标签: entity-framework asp.net-web-api


    【解决方案1】:

    我相信您会因为为您的实体生成动态代理而收到此异常。如果您查看异常消息,您实际上并没有序列化 News 类型,而是 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://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies' 预计不会。 考虑使用 DataContractResolver 或将任何静态未知的类型添加到已知类型列表中 - 例如,使用 KnownTypeAttribute 属性或将它们添加到传递给 DataContractSerializer 的已知类型列表中。

    由于类型是自动创建的,因此您不能放置属性。因此,我将专注于“考虑使用 DataContractResolver”和“将它们添加到传递给 DataContractSerializer 的已知类型列表中”部分。

    顺便说一句,您使用的是什么版本的 EF?我想我之前看到过这个问题,它在 EF5 RTM 中得到了修复。

    【讨论】:

    • 我使用:\EntityFramework.5.0.0\lib\net40\EntityFramework.dll,是的,禁用惰性和代理解决了这个问题,但我不确定这是否是个好主意?
    • 不知道DataContractResolver是什么,google一下吧。
    • 重新禁用延迟加载(或代理创建) - 这取决于您的应用程序是否正在使用它。如果是这样,那么如果您希望自动加载导航属性并且它不会(因为代理创建被禁用),那么您的应用程序将会崩溃
    • 好的,我可能想再次启用代理。但我没有找到让它工作的解决方案。可能需要对 webapi 或 WCF 服务有更多经验的人。 (假设它是同样的问题)。
    • 我在使用 Web API 和 EF 时遇到了类似的问题,这个解决方案解决了我的问题。这可能是一个很好的“确定答案”候选者。
    【解决方案2】:

    当我禁用代理创建时,我在 Mcv5 项目中也遇到了同样的问题,每件事都像魅力一样工作。我希望它也能帮助你。

    DbContext.Configuration.ProxyCreationEnabled = false;
    

    【讨论】:

      【解决方案3】:

      使用 .ToList() 代替 .AsEnumerable。我也很好奇您是如何创建和销毁数据上下文的。

      【讨论】:

      • 我只是把 private TrafficTheoryContext db = new TrafficTheoryContext();在控制器类中。 .AsEnumerable 工作正常 - 我发现禁用延迟加载和代理它可以工作。这是个坏主意吗?
      • @s093294 - 好吧,禁用它会削弱 EF 的部分功能。这意味着您需要明确 .Include() 您要使用的所有表。有些人喜欢这样,有些人不喜欢。此外,没有代理生成意味着没有更改跟踪,更改跟踪对于保持上下文状态同步非常重要。如果您禁用代理创建,那么您必须非常小心如何插入、更新或删除记录。
      • 好的,使用 toList() 也不起作用,它只是一个代理列表。
      • 我从未找到解决方案。 List 或 IEnumerable 无关紧要。
      猜你喜欢
      • 2011-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-30
      • 1970-01-01
      • 1970-01-01
      • 2011-08-18
      • 1970-01-01
      相关资源
      最近更新 更多