【问题标题】:Web API and EF cause InvalidOperationExceptionWeb API 和 EF 导致 InvalidOperationException
【发布时间】:2014-04-27 17:38:20
【问题描述】:

我的解决方案中有 3 个项目:DataModel (EF)、与 DataModel 中的实体和 MVC Web API 一起使用的 DAL。

只有 2 个非常简单的实体:Person、Address,每个实体都有 3 个简单字段,Person 有 Address 字段(因此这两个实体是链接的)

在我的 DAL 中,我有一个方法可以返回所有 Persons 的列表,内容非常简单:return context.Person.ToList();

现在在我的 Web API 中,我只是调用 GetPersons() 方法并尝试返回它。 在这里我收到一条奇怪的错误消息:

"发生错误。","ExceptionMessage":"'ObjectContent`1' type 未能序列化内容类型的响应正文 '应用程序/json; charset=utf-8'.","ExceptionType":"System.InvalidOperationException","StackTrace":null,"InnerException":{"$id":"2","Message":"An 发生错误。",...

当我调试时,我可以看到我确实有来自我的 GetPersons 方法的数据。 我也用谷歌搜索并找到了唯一的解决方案:我应该在我的启动配置中添加以下几行:

var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);

但这无济于事。

我还尝试在不使用数据库的情况下手动填充列表:在这种情况下它可以工作。

我有一个强烈的印象,它与 EF 有关,但我不知道具体是什么。

【问题讨论】:

    标签: entity-framework asp.net-mvc-4 rest asp.net-web-api


    【解决方案1】:
    • 分步指南...

    第 1 步:转到您的实体项目,然后找到继承自 DbContext 类的类的名称。

    例如:如果类名是MyProjectEntities如下:

    public partial class MyProjectEntities : DbContext
    {
       //Auto Generated statements if EF is used.
    }
    

    第 2 步:转到您的 WebApi 项目,找到从 ApiController 继承的控制器,然后在该控制器中为 MyProjectEntities 类创建实例。

    例如:如果 Api Controller 名称是 PersonController,则为 MyProjectEntities 创建实例,如下所示:

    public class PersonController : ApiController
    {
       MyProjectEntities DB = new MyProjectEntities();
    }
    

    步骤 3: 为 PersonController 类创建构造函数,并将 ProxyCreationEnabled 属性设置为 false,如下所示:

    public PersonController()
    {
       DB.Configuration.ProxyCreationEnabled = false;
    }
    

    Web api 控制器中的最终代码如下所示:

    public class PersonController : ApiController
    {
       MyProjectEntities DB = new MyProjectEntities();
       public PersonController()
       {
          DB.Configuration.ProxyCreationEnabled = false;
       }
    ...
    ...
    

    【讨论】:

      【解决方案2】:

      该错误是由序列化数据时 Person 和 Address 实体之间的交叉引用引起的。您还应该添加这一行

      json.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
      

      更多来自here

      【讨论】:

      • 仍然报错:{"$id":"1","Message":"发生错误。","ExceptionMessage":"'ObjectContent`1'类型序列化失败内容类型 'application/json; charset=utf-8' 的响应正文。","ExceptionType":"System.InvalidOperationException","StackTrace":null,"InnerException":{"$id":"2", "Message":"发生错误。","ExceptionMessage":"从 'System.Data.Entity.DynamicProxies.address.... 上的 'address' 获取值时出错....
      【解决方案3】:

      您可以更改 Get 方法,让您的 api 使用 ToList()、ToArray() 等返回对象列表。

      例如,如果您的 Get 方法是这样的。

      public IQueryable<Language> GetLanguages()
      {
        return db.Languages;
      }
      

      你可以改成

      public IEnumerable<Language> GetLanguages()
      {
          return db.Languages.ToArray();
      }
      

      返回对象数组并且没有序列化错误。但是解决这个问题的正确方法是告诉here详细。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-02-09
        • 2021-07-22
        • 2022-01-11
        • 2017-09-20
        • 1970-01-01
        • 2012-05-08
        • 1970-01-01
        相关资源
        最近更新 更多