我遇到了在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设置允许任何来源。如果我在return Ok(products)
上设置断点并且Includes()
调用未注释,我可以看到数据正被添加到products
对象。
为什么响应会失败?
答案 0 :(得分:5)
这是json序列化程序的循环引用问题。
您可以通过在Startup.cs
文件中添加以下配置来解决此问题:
services.AddMvc()
.AddJsonOptions(option =>
{
option.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});