ASP.NET Core 7 MVC中ItemOrVm属性在Create方法中为何为null?
问题:Index()方法中ItemOrVm正常填充,但Create()方法中该属性变为null的原因?
调用Index()方法时,ItemOrVm属性会被正常填充数据;但调用Create()方法时,ItemOrVm属性却变为null,请问这一重置现象的原因是什么?相关代码如下:
public class ItemsController : Controller { private readonly IOrderRepository _orderRepository; private readonly IItemsOrRepository _itemsOrRepository; [BindProperty] public ItemOrVM? ItemOrVm { get; set; } public ItemsController(IItemsOrRepository itemsOrRepository, IOrderRepository orderRepository) { _itemsOrRepository = itemsOrRepository; _orderRepository = orderRepository; } [HttpGet] public IActionResult Index(int id) { ViewBag.OrderId = id; this.ItemOrVm = new ItemOrVM() { Order = _orderRepository.FirstOfDefault(u => u.Id == id), OrderItems = _itemsOrRepository.GetAll(u => u.OrderId == id) }; return View(ItemOrVm); } [HttpGet] public IActionResult Create(int? orderId, int? itemId) { ViewBag.OrderId = this.ItemOrVm!.Order!.Id; if (itemId != null) { OrderItem orderItems = _itemsOrRepository.FirstOfDefault(u => u.Id == itemId); return View(orderItems); } return View(); } }
注:使用不同模型的类似代码在.NET 5.0中可正常运行。
原因分析
控制器实例生命周期导致状态不保留:ASP.NET Core(包括.NET 5及后续版本)的控制器是请求级实例——每个HTTP请求都会创建一个全新的控制器对象。你在Index()请求中给
ItemOrVm赋值,这个值只属于当前请求的控制器实例;当发起Create()的新请求时,系统会生成一个全新的ItemsController实例,这个新实例的ItemOrVm默认就是null,自然无法获取之前请求中的数据。.NET 5的“正常运行”是巧合:你提到的.NET 5中类似代码能运行,大概率是偶然场景(比如极端情况下的请求复用实例,但这不符合框架设计规范),ASP.NET Core的控制器生命周期设计从始至终都是请求级的,跨请求不会保留实例成员的状态。
当前代码的逻辑错误:Create()方法中直接访问
this.ItemOrVm!.Order!.Id会触发空引用异常,正确的做法是利用方法参数orderId来查询对应的Order数据,而非依赖前一个请求的控制器属性。
内容的提问来源于stack exchange,提问作者Ruslan
相关产品推荐
相关产品推荐

