【问题标题】:ASP.NET Web API - Entity Framework - 500 Internal Server Error On .Include(param => param.field)ASP.NET Web API - 实体框架 - 500 内部服务器错误 .Include(param => param.field)
【发布时间】:2012-07-29 22:48:52
【问题描述】:

我目前正在使用实体框架(我知道它还不是最稳定的平台)使用 Database-First 方法开发一个 Web API 项目,但我遇到了一些非常奇怪的事情。

当我的 APIController 中的 GET 方法尝试使用涉及的 LINQ Include() 方法返回 DbSet 中的所有记录时,它将返回 500 错误:

// GET api/Casinos
    public IEnumerable<casino> Getcasinos()
    {
            var casinos = db.casinos.Include(c => c.city).Include(c => c.state);
            return casinos.AsEnumerable();
        }

然而,这个方法工作正常,并从我的数据库中返回我的数据:

// GET api/States
    public IEnumerable<state> Getstates()
    {
        return db.states.AsEnumerable();
    }

所以我已经在其他情况下证明,如果它返回没有 LINQ 查询的实体,效果很好,但是当在 DbContext 上使用 Include 方法时,它会失败。

当然,试图找到这个错误是不可能的,即使使用 Fiddler、Chrome/Firefox 开发工具,并添加 GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;

如果有人解决了这个问题,很高兴知道一个好的解决方案,这样我就可以开始返回我的数据了!谢谢!:)

附:我正在使用 SQL Server 2012

【问题讨论】:

  • 您可以创建一个自定义的 ExceptionFilterAttribute,您可以注册它以查看错误详细信息。有关示例,请参见 asp.net/web-api/overview/web-api-routing-and-actions/…
  • 你在 fiddler 或 Chrome 中得到了什么,只是一般的 500 页错误?
  • 你不能只附加一个调试器来获取根异常吗?否则尝试/捕获整个 get 然后记录/抛出
  • @CuongLe 是的,我只是遇到了一个普遍的例外情况。我通过删除 XML 格式化程序来修复它,但我真的希望我不必这样做,因为我希望它返回 JSON 和 XML,但我想这是一个限制?

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


【解决方案1】:

这是由于序列化错误 (Json/XML) 造成的。问题是您直接尝试通过网络传输模型。举个例子,看看这个:

public class Casino
{
    public int ID { get; set; }
    public string Name { get; set; }

    public virtual City City { get; set; }
}

public class State
{
    public int ID { get; set; }
    public string Name { get; set; }

    [XmlIgnore]
    [IgnoreDataMember]        
    public virtual ICollection<City> Cities { get; set; }
}

public class City
{
    public int ID { get; set; }
    public string Name { get; set; }

    public virtual  State State { get; set; }

    [XmlIgnore]
    [IgnoreDataMember]
    public virtual ICollection<Casino> Casinos { get; set; }
}

public class Context : DbContext
{
    public Context()
        : base("Casino")
    {

    }

    public DbSet<Casino> Casinos { get; set; }
    public DbSet<State> States { get; set; }
    public DbSet<City> Cities { get; set; }
}

注意XmlIgnoreIgnoreDataMember。您需要限制避免序列化,这样它就不会以循环方式发生。此外,上述模型仍然无法工作,因为它具有虚拟。从任何地方删除虚拟,即CityCitiesCasinosState,然后它会起作用,但效率会很低。

总结一下:使用 DTO,只发送你真正想发送的数据,而不是直接发送你的模型。

希望这会有所帮助!

【讨论】:

  • 谢谢安东尼!我猜默认生成的设计不是最好的。我会做出必要的改变,看看我是否还能保持良好的设计实践。
【解决方案2】:

我在 ASP.Net Core Web Api 中遇到了同样的问题,并使它与这个解决方案一起工作: 将 Microsoft.AspNetCore.Mvc.NewtonsoftJson nuget 包添加到 web api 项目。 并在 ConfigureServices 方法的 Startup.cs 类中添加以下代码:

services.AddControllersWithViews().AddNewtonsoftJson(options =>
 options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-28
    • 1970-01-01
    • 2017-03-07
    • 1970-01-01
    • 2018-08-03
    • 1970-01-01
    • 2017-10-28
    • 2015-07-20
    相关资源
    最近更新 更多