2014-11-24 2 views
-1

Я написал очень простой пользовательский атрибут проверки, чтобы проверить буквенно-цифровую строку, и она работает на стороне сервера, но я получаю исключение NullReferenceException для validationContext при попытке использовать модель клиентской стороны проверка в .NET MVC. Мой пользовательский атрибут написан в отдельной библиотеке классов, используемой приложением MVC. Атрибуте и валидатор классы здесь:Клиентская ошибка клиента MVC .NET с атрибутом пользовательской проверки

/// <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 }; 
     } 
    } 

Я тогда простой класс модели в моем приложении MVC с аннотацией данных с использованием [буквенно-цифровой] декоратора:

[Required, Display(Name = "Product Code"), AlphaNumeric] 
     public string ProductCode { get; set; } 

Наконец у меня есть мой контроллер будучи прошел класс модели и использовать стандартный ModelState.IsValid способ проверки ...

[HttpPost] 
public ActionResult Index(CreateModel Model) 
{ 
    if (ModelState.IsValid) 
    { 
     // Do some stuff 
    } 
    else return View(Model); 
} 

Когда я получить доступ к своему веб-форму и отправить, я сразу же получить нулевую эталонную исключение до того, как когда-либо вызывается метод действия контроллера:

[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 

Что мне здесь не хватает? Если я использую другие встроенные аннотации данных, такие как регулярное выражение и т. Д., Я не получаю эту ошибку. Нужно ли мне регистрировать какой-либо обработчик с помощью приложения MVC? Я действительно в недоумении с этим. И да, я мог бы использовать простой атрибут проверки регулярного выражения для чего-то такого простого, но мне нужно понять корень проблемы, поскольку у меня есть много более сложных атрибутов проверки для написания и хотелось бы понять, как правильно их подключить. Спасибо ...

ответ

0

Рик, вам нужны дополнительные вещи для этого, чтобы работать на стороне клиента. Вот хороший учебник о том, как это осуществить: http://thewayofcode.wordpress.com/tag/custom-unobtrusive-validation/

+0

Спасибо за ваш ответ. Оказывается, это была проверка на стороне сервера, которая была взломана, потому что я не создавал свою форму в представлении с помощью помощника Html.BeginForm(), который необходим для привязки validationContext. Я просто создал свой собственный тег формы. –

+0

Я говорил слишком рано - я все еще получаю сообщение об ошибке с использованием настраиваемого атрибута, и я хочу только выполнить проверку на стороне сервера. –

+0

@RickClift - вам, вероятно, нужно изменить возвращаемое значение от нуля до объекта ValidationResult в методе IsValid. Вы всегда должны возвращать объект, а не просто null. – Eduardo

Смежные вопросы