asp.net - 阻止 ASP.NET MVC 调用模型类中的所有 getter

标签 asp.net asp.net-mvc model-binding

如果你在你的模型类上定义了以下两个属性,这将崩溃并返回 NullReferenceException。在模型绑定(bind)期间:

        public Customer Customer { get; private set; } //set in the action method
        public bool Name => Customer.Name;

这是因为 Customer在模型绑定(bind)期间仍然为空,并且 ASP.NET MVC 调用 Name 的 getter .

堆栈是:
   System.ComponentModel.ReflectPropertyDescriptor.GetValue(Object component) +525
   System.Web.Mvc.ModelMetadata.get_Model() +34
   System.Web.Mvc.DataAnnotationsModelValidator.Validate(Object container) +151
   System.Web.Mvc.<Validate>d__1.MoveNext() +387
   System.Web.Mvc.DefaultModelBinder.OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext) +163
   System.Web.Mvc.DefaultModelBinder.BindComplexElementalModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Object model) +83
   System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +1754
   System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +460
   System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +137
   System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +982
   System.Web.Mvc.<>c__DisplayClass22.<BeginExecuteCore>b__1e() +39
   System.Web.Mvc.Async.AsyncResultWrapper.<.cctor>b__0(IAsyncResult asyncResult, Action action) +21
   System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +53
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +36
   System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +38
   System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +44
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +65
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +38
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +399
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +137

从堆栈看起来模型验证正在查询所有 getter。我没有使用模型验证。

我该如何处理这种情况?我可以让 ASP.NET MVC 在没有任何(明显)原因的情况下不调用所有 getter 吗?

最佳答案

因此,Model Binder 新建了您的模型的一个实例,然后可能正在对模型的属性进行反射以查找与 FormCollection 中的值匹配的命名。发生的情况是,当调用危险的 Name Prop 时,Customer Prop 为空,因此 NullRef。

.NET 检查这些属性的顺序实际上可能不是随机的,但只要这样处理,您的代码就会得到很大改进。在默认情况下可以为空的类上直接调用方法/ Prop 是一个糟糕的主意,除非您检查它是否为空。您在这里有两个选择,或者 (1) 重新设计您的模型类,以便构造函数初始化“客户”属性,或者 (b) 在该“名称”方法中添加一个空检查。

这是在您抓取它时对其进行空检查的最简单方法:

public bool Name => Customer?.Name ?? false;

这并不能解决根本问题,即您有一个模型,该模型具有链接在一起的可为空的 Prop 。不要担心模型的构造函数会弄乱模型绑定(bind)。 Model Binder 将 (1) 初始化您的模型类,然后 (2) 尝试对其进行水合。因此,在模型的构造函数中初始化客户类/ Prop 不会影响 UI 字段的任何映射,即客户的字段。

关于asp.net - 阻止 ASP.NET MVC 调用模型类中的所有 getter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37840554/

相关文章:

asp.net - ASP :TextBox ReadOnly=true or Enabled=false?

jquery - 纯AJAX架构的ASP.Net开发

c# - 在 ASP.NET MVC 操作中隐式声明参数

asp.net-mvc-4 - 绑定(bind)可变数量的输入

asp.net-mvc - ASP.NET MVC 4 - ModelBinder 错误

asp.net-mvc-3 - 模型绑定(bind)逗号分隔的查询字符串参数

javascript - RadioButtonList 发送空字符串

asp.net - 在数据库中存储日期时间?

c# - Angular 5 Uncaught( promise 中): Error: StaticInjectorError(AppModule)

asp.net-mvc - ASP.NET MVC 中的语言相关路由