【问题标题】:Entity Framework Core: Includes Breaks Http Response实体框架核心:包括中断 Http 响应
【发布时间】:2018-02-11 16:27:05
【问题描述】:

我在 Entity Framework Core 和 Asp .NET Core 中设置简单的多对多关系时遇到了问题,这让我抓狂。每当我尝试使用 Includes() 方法返回相关集合时,我的 HTTP 响应都会中断。有人可以帮帮我吗?

快速演示,下面简单介绍一下Product和Category类的关系:

public class Product
{
    public int ProductId { get; set; }
    public string Name { get; set; }
    public ICollection<ProductCategory> ProductCategories { get; set; }
}

public class Category
{
    public int CategoryId { get; set; }
    public string Name { get; set; }
    public ICollection<ProductCategory> ProductCategories { get; set; }
}

public class ProductCategory
{
    public int ProductId { get; set; }
    public int CategoryId { get; set; }
    public Product Product { get; set; }
    public Category Category { get; set; }
}

以及实体框架 DbContext:

public class ProductDbContext : DbContext
{
    public DbSet<Product> Products { get; set; }
    public DbSet<Category> Categories { get; set; }
    public DbSet<ProductCategory> ProductCategories { get; set; }

    public ProductDbContext(DbContextOptions<ProductDbContext> options) : base(options)
    {

    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<ProductCategory>().HasKey(s => new { s.ProductId, s.CategoryId });

        base.OnModelCreating(modelBuilder);
    }
}

还有一个控制器,它带有一个 Set 方法(只是播种数据的一种快速方法)和一个 Get 方法来实际获取结果:

public class ProductController : Controller
{
    ProductDbContext _context;

    public ProductController(ProductDbContext context)
    {
        _context = context;
    }

    public IActionResult Set()
    {
        _context.Products.AddRange(
            new Product
            {
                Name = "TestProduct1"
            },
            new Product
            {
                Name = "TestProduct2"
            }
            );

        _context.Categories.AddRange(
            new Category
            {
                Name = "TestCategory1"
            },
            new Category
            {
                Name = "TestCategory2"
            }
            );

        _context.SaveChanges();

        _context.ProductCategories.AddRange(
            new ProductCategory
            {
                ProductId = 1,
                CategoryId = 1
            },
            new ProductCategory
            {
                ProductId = 2,
                CategoryId = 1
            },
            new ProductCategory
            {
                ProductId = 2,
                CategoryId = 2
            }
            );

        _context.SaveChanges();

        return Ok();
    }

    public IActionResult Get()
    {
        var products = _context.Products
            //.Include(p => p.ProductCategories)
            .ToList();
        return Ok(products);
    }
}

为了测试,首先我通过 Postman (http://localhost:54551/product/set) 使用 Set 方法。在此之后,点击 Get 方法 (http://localhost:54551/product/get) 将返回:

[
    {
        "productId": 1,
        "name": "TestProduct1",
        "productCategories": null
    },
    {
        "productId": 2,
        "name": "TestProduct2",
        "productCategories": null
    }
]

但是,取消注释 Get 方法中对 Includes 的调用会给我以下信息:

无法得到任何回应

There was an error connecting to http://localhost:54551/product/get.
Why this might have happened:
The server couldn't send a response:
Ensure that the backend is working properly
Self-signed SSL certificates are being blocked:
Fix this by turning off 'SSL certificate verification' in Settings > General
Proxy configured incorrectly
Ensure that proxy is configured correctly in Settings > Proxy
Request timeout:
Change request timeout in Settings > General

我错过了什么?我设置了 CORS 以允许任何来源。如果我在Includes() 调用未注释的情况下在return Ok(products) 上设置断点,我可以看到数据正在添加到products 对象中。

为什么响应会失败?

【问题讨论】:

  • 我想响应失败,因为您的代码抛出异常。尝试调试以查看发生了什么。
  • 可能你有循环引用。 (产品 -> 产品类别 -> 产品)

标签: c# entity-framework asp.net-core entity-framework-core


【解决方案1】:

这是 json 序列化器的循环引用问题。 您可以通过在Startup.cs 文件中添加以下配置来解决此问题:

services.AddMvc()
    .AddJsonOptions(option =>
    {
        option.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
    });

【讨论】:

  • 正是我所缺少的。非常感谢!
  • 天哪,这个问题花了我 2 个小时
  • 非常感谢您的提示。我知道为了让它工作而缺少配置的一部分;-)
猜你喜欢
  • 2020-05-24
  • 2017-11-15
  • 2021-04-03
  • 1970-01-01
  • 2021-05-16
  • 1970-01-01
  • 1970-01-01
  • 2021-07-14
  • 1970-01-01
相关资源
最近更新 更多