2013-10-29 41 views
1

我似乎无法重写数值字段的MVC验证的默认行为。MVC数字验证

我创建了一个默认的MVC4项目来表示我的问题。

模型(默认的MVC 4个构造适合你,加上两个属性“年龄”和“日期”):

[Required] 
    [Display(Name = "User name")] 
    public string UserName { get; set; } 

    [Required] 
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] 
    [DataType(DataType.Password)] 
    [Display(Name = "Password")] 
    public string Password { get; set; } 

    [DataType(DataType.Password)] 
    [Display(Name = "Confirm password")] 
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] 
    public string ConfirmPassword { get; set; } 

    public DateTime Date { get; set; } 

    public int Age { get; set; } 

所以默认MVC验证我创建了两个领域,我获取以下验证消息:“字段”年龄“是必需的”和“字段”日期“是必需的”

现在我想实现的是迫使我的应用程序忽略默认数字验证在客户端执行此操作,并且用户无法输入无效值)。我试图迫使MVC不添加默认的“必需的”属性非空的属性:

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false; 

这给了我一些进展。现在它不会执行“必需”验证,但发布表单会生成两个相同的验证消息:“需要值”。

除此之外,我无法取得任何成就。我试图消除ClientDataTypeModelValidatorProvider

 foreach (ModelValidatorProvider prov in ModelValidatorProviders.Providers) 
     { 
      if (prov.GetType().Equals(typeof(ClientDataTypeModelValidatorProvider))) 
      { 
       break; 
      } 
     } 

以及完全

ModelValidatorProviders.Providers.Clear(); 

所有供应商没有任何成功。

我也试着重载MVC在DataAnnotationsModelValidatorProvider中使用的一些默认属性,但是这没有给我带来任何结果。

所以有几个问题我想请教一下这种情况:

  1. 是否有可能迫使MVC不要做默认的验证服务器端不可为空的数据类型?如果可能如何?
  2. 是否可以更改问题1中描述的验证的默认行为?如果可能 - 如何?
  3. 是否有可能强制MVC使用我的自定义验证器/验证属性而不是此自定义属性?如果可能 - 如何?

另外一张纸条:我做想写我的属性,它确实验证了我,并把它的每一个属性它应该做验证。我正在寻找一个解决方案,这将允许我定义关于如何完成默认验证的规则。

在此先感谢或有任何建议。

+0

制作日期和年龄可为空的日期时间和int – LostInComputer

+0

我不想做了许多的原因。数据类型必须不能为空。 – Buduls

回答

1

创建您自己的ModelBinder int。然后使该错误返回0。

public class IntModelBinder : IModelBinder 
{ 
    public object BindModel(ControllerContext controllerContext, 
     ModelBindingContext bindingContext) 
    { 
     ValueProviderResult valueResult = bindingContext.ValueProvider 
      .GetValue(bindingContext.ModelName); 
     ModelState modelState = new ModelState { Value = valueResult }; 
     object actualValue = null; 
     try 
     { 
      actualValue = Convert.ToInt32(valueResult.AttemptedValue, 
       System.Globalization.CultureInfo.InvariantCulture); 
     } 
     catch (FormatException e) 
     { 
      //Uncomment for default error 
      //modelState.Errors.Add(e); 
      actualValue = 0; 
     } 

     bindingContext.ModelState.Add(bindingContext.ModelName, modelState); 
     return actualValue; 
    } 
} 

And in Global。ASAX Application_Start()

ModelBinders.Binders.Add(typeof(int), new IntModelBinder()); 
+0

很好的答案!似乎工作得很好。 – Buduls