5

我目前正在使用实体框架(我知道它还不是最稳定的平台)开发一个使用数据库优先方法的 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;

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

PS 我正在使用 SQL Server 2012

4

2 回答 2

4

这是由于序列化错误(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。您需要限制避免序列化,这样它就不会以循环方式发生。此外,上述模型仍然无法工作,因为它具有虚拟。从任何地方删除 virtual ,即City, CitiesCasinos然后State它会起作用,但这会效率低下。

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

希望这可以帮助!

于 2012-08-14T07:39:23.563 回答
1

我在 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
);
于 2020-06-12T21:13:37.140 回答