C# 具有自定义验证属性的.NET MVC错误客户端

C# 具有自定义验证属性的.NET MVC错误客户端,c#,asp.net-mvc,data-annotations,validationattribute,C#,Asp.net Mvc,Data Annotations,Validationattribute,我已经编写了一个非常简单的自定义验证属性来检查字母数字字符串,它在服务器端工作,但是当尝试在.NET MVC中使用客户端模型验证时,我得到了validationContext的NullReferenceException。我的自定义属性写在MVC应用程序使用的单独类库中。属性和验证程序类如下所示: /// <summary> /// Custom validation attribute for an alphanumeric string /// </summ

我已经编写了一个非常简单的自定义验证属性来检查字母数字字符串,它在服务器端工作,但是当尝试在.NET MVC中使用客户端模型验证时,我得到了validationContext的NullReferenceException。我的自定义属性写在MVC应用程序使用的单独类库中。属性和验证程序类如下所示:

/// <summary>
    /// Custom validation attribute for an alphanumeric string
    /// </summary>
    public class AlphaNumericAttribute : ValidationAttribute
    {
        public AlphaNumericAttribute()
            : base()
        {
            ErrorMessage = ValidationMessages.AlphaNumeric;
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            var RegExMatch = ValidationExpressions.AlphaNumeric.Match(value.ToString());
            if (!RegExMatch.Success)
            {
                return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName));
            }
            return null;
        }
    }

    /// <summary>
    /// Custom validator class for the AlphaNumeric attribute defined above.
    /// </summary>
    public class AlphaNumericValidator : DataAnnotationsModelValidator<AlphaNumericAttribute>
    {
        string errorMsg = string.Empty;

        public AlphaNumericValidator(ModelMetadata metadata,
        ControllerContext controllerContext, AlphaNumericAttribute attribute)
            : base(metadata, controllerContext, attribute) 
        {
            errorMsg = attribute.ErrorMessage;
        }

        public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
        {
            ModelClientValidationRule validationRule = new ModelClientValidationRule();
            validationRule.ValidationType = "alphanumeric";
            validationRule.ErrorMessage = Attribute.FormatErrorMessage(Metadata.DisplayName);
            return new[] { validationRule };
        }
    }
最后,我让我的控制器通过模型类,并使用标准的ModelState.IsValid方法验证

[HttpPost]
public ActionResult Index(CreateModel Model)
{
   if (ModelState.IsValid)
   {
      // Do some stuff
   }
   else return View(Model);
}
当我访问我的web表单并提交时,我会在调用控制器的操作方法之前立即收到空引用异常:

[NullReferenceException: Object reference not set to an instance of an object.]
   LibData.Validation.AlphaNumericAttribute.IsValid(Object value, ValidationContext validationContext) +75
   System.ComponentModel.DataAnnotations.ValidationAttribute.GetValidationResult(Object value, ValidationContext validationContext) +29
   System.Web.Mvc.DataAnnotationsModelValidator.Validate(Object container) +372
   System.Web.Mvc.<Validate>d__1.MoveNext() +393
   System.Web.Mvc.DefaultModelBinder.OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext) +401
   System.Web.Mvc.DefaultModelBinder.BindComplexElementalModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Object model) +123
   System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +2541
   System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +633
   System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +496
   System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +199
   System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__19(AsyncCallback asyncCallback, Object asyncState) +1680
   System.Web.Mvc.Async.WrappedAsyncResult`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +59
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
   System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate`1 endDelegate, Object tag, Int32 timeout) +94
   System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state) +559
   System.Web.Mvc.Controller.<BeginExecuteCore>b__1c(AsyncCallback asyncCallback, Object asyncState, ExecuteCoreState innerState) +82
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +73
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
   System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext) +105
   System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback, Object state) +588
   System.Web.Mvc.Controller.<BeginExecute>b__14(AsyncCallback asyncCallback, Object callbackState, Controller controller) +47
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +65
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
   System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext) +139
   System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +484
   System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +50
   System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__4(AsyncCallback asyncCallback, Object asyncState, ProcessRequestState innerState) +98
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +73
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
   System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext) +106
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +446
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +88
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +50
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +301
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
[NullReferenceException:对象引用未设置为对象的实例。]
LibData.Validation.alphanumericatAttribute.IsValid(对象值,ValidationContext ValidationContext)+75
System.ComponentModel.DataAnnotations.ValidationAttribute.GetValidationResult(对象值,ValidationContext ValidationContext)+29
System.Web.Mvc.DataAnnotationsModelValidator.Validate(对象容器)+372
System.Web.Mvc.d__1.MoveNext()+393
System.Web.Mvc.DefaultModelBinder.OnModelUpdated(ControllerContext ControllerContext,ModelBindingContext bindingContext)+401
System.Web.Mvc.DefaultModelBinder.BindCompleteXelementalModel(ControllerContext ControllerContext,ModelBindingContext bindingContext,Object model)+123
System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext ControllerContext,ModelBindingContext bindingContext)+2541
System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext ControllerContext,ModelBindingContext bindingContext)+633
System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext ControllerContext,ParameterDescriptor ParameterDescriptor)+496
System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext ControllerContext,ActionDescriptor ActionDescriptor)+199
System.Web.Mvc.Async.c__显示类21.b__19(AsyncCallback AsyncCallback,Object asyncState)+1680
System.Web.Mvc.Async.WrappedAsyncResult`1.CallBeginDelegate(AsyncCallback回调,对象callbackState)+59
System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(异步回调,对象状态,Int32超时)+151
System.Web.Mvc.Async.AsyncResultRapper.Begin(AsyncCallback回调,对象状态,BeginInvokeDelegate beginDelegate,EndInvokeDelegate`1 endDelegate,对象标记,Int32超时)+94
System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext ControllerContext,String actionName,AsyncCallback回调,对象状态)+559
System.Web.Mvc.Controller.b_uu1c(AsyncCallback-AsyncCallback,Object-asyncState,executeRecreat-innerState)+82
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback回调,对象callbackState)+73
System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(异步回调,对象状态,Int32超时)+151
System.Web.Mvc.Async.AsyncResultRapper.Begin(AsyncCallback回调,对象callbackState,BeginInvokeDelegate`1 beginDelegate,EndInvokeVoidDelegate`1 endDelegate,TState invokeState,对象标记,Int32超时,SynchronizationContext callbackSyncContext)+105
System.Web.Mvc.Controller.BeginExecuteCore(异步回调,对象状态)+588
System.Web.Mvc.Controller.b_uu14(异步回调、异步回调、对象回调、控制器控制器)+47
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback回调,对象callbackState)+65
System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(异步回调,对象状态,Int32超时)+151
System.Web.Mvc.Async.AsyncResultRapper.Begin(AsyncCallback回调、对象callbackState、BeginInvokeDelegate`1 beginDelegate、EndInvokeVoidDelegate`1 endDelegate、TSState invokeState、对象标记、Int32超时、SynchronizationContext callbackSyncContext)+139
System.Web.Mvc.Controller.BeginExecute(RequestContext RequestContext,AsyncCallback回调,对象状态)+484
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.BeginExecute(RequestContext RequestContext,AsyncCallback回调,对象状态)+50
System.Web.Mvc.MvcHandler.b_uu4(AsyncCallback AsyncCallback,Object asyncState,ProcessRequestState innerState)+98
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback回调,对象callbackState)+73
System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(异步回调,对象状态,Int32超时)+151
System.Web.Mvc.Async.AsyncResultRapper.Begin(AsyncCallback回调,对象callbackState,BeginInvokeDelegate`1 beginDelegate,EndInvokeVoidDelegate`1 endDelegate,TState invokeState,对象标记,Int32超时,SynchronizationContext callbackSyncContext)+106
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext,异步回调,对象状态)+446
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext HttpContext,异步回调,对象状态)+88
System.Web.Mvc.MvcHandler.System.Web.IHTTPassynchandler.BeginProcessRequest(HttpContext上下文,AsyncCallback cb,Object extraData)+50
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()+301
System.Web.HttpApplication.ExecuteStep(IExecutionStep步骤,布尔值&同步完成)+155

我错过了什么?如果我使用其他内置的数据注释,如正则表达式等,我不会得到这个错误。我是否需要向MVC应用程序注册某种处理程序?我对这件事真是不知所措。是的,我可以用一个简单的正则表达式验证属性来完成这么简单的事情,但是我需要理解问题的根源,因为我有很多更复杂的验证属性要写,并且想知道如何适当地连接它们。谢谢……

瑞克,你确实需要一些额外的东西
[NullReferenceException: Object reference not set to an instance of an object.]
   LibData.Validation.AlphaNumericAttribute.IsValid(Object value, ValidationContext validationContext) +75
   System.ComponentModel.DataAnnotations.ValidationAttribute.GetValidationResult(Object value, ValidationContext validationContext) +29
   System.Web.Mvc.DataAnnotationsModelValidator.Validate(Object container) +372
   System.Web.Mvc.<Validate>d__1.MoveNext() +393
   System.Web.Mvc.DefaultModelBinder.OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext) +401
   System.Web.Mvc.DefaultModelBinder.BindComplexElementalModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Object model) +123
   System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +2541
   System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +633
   System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +496
   System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +199
   System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__19(AsyncCallback asyncCallback, Object asyncState) +1680
   System.Web.Mvc.Async.WrappedAsyncResult`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +59
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
   System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate`1 endDelegate, Object tag, Int32 timeout) +94
   System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state) +559
   System.Web.Mvc.Controller.<BeginExecuteCore>b__1c(AsyncCallback asyncCallback, Object asyncState, ExecuteCoreState innerState) +82
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +73
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
   System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext) +105
   System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback, Object state) +588
   System.Web.Mvc.Controller.<BeginExecute>b__14(AsyncCallback asyncCallback, Object callbackState, Controller controller) +47
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +65
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
   System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext) +139
   System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +484
   System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +50
   System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__4(AsyncCallback asyncCallback, Object asyncState, ProcessRequestState innerState) +98
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +73
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
   System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext) +106
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +446
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +88
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +50
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +301
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155