ASP.NET Web API - 实体框架 - 500 内部服务器错误打开。包含(param => param.field)



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

当我的APIController中的GET方法试图返回DbSet中的所有记录,并包含LINQ Include()方法时,它将返回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

这是由于序列化(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,只发送您真正想要发送的数据,而不是直接发送您的模型。

希望这能有所帮助!

我在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
);

最新更新