MVC数字验证

时间:2013-10-29 11:37:10

标签: c# asp.net-mvc validation asp.net-mvc-4 numeric

我似乎没有办法覆盖数字字段的MVC验证的默认行为。

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

模型(默认的MVC 4构造,加上两个属性“Age”和“Date”):

    [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会验证我创建的两个字段,并且我收到以下验证消息:“字段”Age“是必需的”和“字段”日期“是必需的”

现在我想要实现的是强制我的应用程序忽略默认的数字验证(我在客户端这样做,并且用户无法输入无效值)。我试图强制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使用我的自定义验证器/验证属性而不是此自定义验证器?如果可能 - 怎么样?
  4. 还要注意:我想要编写我的属性,为我做验证并将其放在应该进行验证的每个属性上。我正在寻找一个解决方案,这将允许我定义关于如何进行默认验证的规则。

    提前致谢或提出任何建议。

1 个答案:

答案 0 :(得分:1)

int创建自己的ModelBinder。然后使该绑定器在出错时返回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;
    }
}

在Global.asax Application_Start()中:

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