我正在开发 ASP.NET Core MVC 应用程序,并且遇到了一种情况,我正在尝试创建与订单关联的项目。我使用下拉列表来选择 OrderID,这工作正常,但我遇到了一个问题,即 Item 的 Order 导航属性始终为 null,这导致 ModelState 无效。
这是我的物品模型的简化版本:
public class Item
{
[Key]
public int ItemID { get; set; }
public string ItemName { get; set; }
public decimal Price { get; set; }
public int QuantityInStock { get; set; }
public int OrderID { get; set; }
public Order Order { get; set; }
}
我使用 _ordersService 在 GET 操作中获取有效的 OrderID 值以创建项目。在 POST 操作中,我使用选定的 OrderID 将项目与订单关联起来。
这是我的创建操作:
// GET: Items/Create
public IActionResult Create()
{
var itemsWithOrders = _ordersService.GetAllOrders();
var orderIDs = itemsWithOrders.Select(item => new
{
item.OrderID,
}).ToList();
ViewBag.OrderIDList = new SelectList(orderIDs, "OrderID", "OrderID");
return View();
}
// POST: Items/Create
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create([Bind("ItemName,Price,QuantityInStock,OrderID")] Item item)
{
if (ModelState.IsValid)
{
_itemsService.CreateItem(item);
return RedirectToAction(nameof(Index));
}
// Additional code to handle ModelState errors
return View(item);
}
问题是,当我创建一个 Item 时,Order 导航属性保持为 null,这会导致 ModelState 无效。我怀疑该问题可能与我如何将商品与订单相关联。
如何确保在创建项目时正确填充订单导航属性?可能是什么导致它为空,我该如何解决这个问题?
根据您的代码,您直接在视图内使用数据模型(Item),由于Item包含客户端不会返回的Order属性,因此模型验证将始终为false,因为Order始终为空。
一种可能的解决方案是使用 Modlestate.Remove 方法来删除订单验证,如下所示:
ModelState.Remove("Order");
但我不建议你这样做,我建议你可以创建一个新的视图模型来处理视图数据,然后使用一些地图服务将视图模型与数据模型映射。
始终记住,将数据模型直接暴露给视图可能会导致安全风险(例如批量分配漏洞)或意外的数据暴露。始终使用 ViewModel 或 DTO 仅向视图或客户端公开所需的数据。