mvc3 验证输入“不等于”

Posted

技术标签:

【中文标题】mvc3 验证输入“不等于”【英文标题】:mvc3 validate input 'not-equal-to' 【发布时间】:2011-08-09 20:27:09 【问题描述】:

我的表单具有默认帮助文本的输入,可指导用户输入内容(而不是使用标签)。这使得验证变得棘手,因为输入值永远不会为空。

如何扩展不显眼的验证来处理这个问题?如果名称输入等于“请输入您的姓名...”,则该表单应该无效

我开始阅读关于验证适配器的Brad Wilson's blog post,但我不确定这是否是正确的方法?我需要能够根据字段验证不同的默认值。

谢谢

【问题讨论】:

或者,考虑使用placeholder attribute 显示指令文本,例如“请输入您的姓名...”,作为一种更友好的用户体验和符合 html5 标准的方式向用户提供提示。 【参考方案1】:

这是一个示例,说明如何继续实施自定义验证属性:

public class NotEqualAttribute : ValidationAttribute, IClientValidatable

    public string OtherProperty  get; private set; 
    public NotEqualAttribute(string otherProperty)
    
        OtherProperty = otherProperty;
    

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    
        var property = validationContext.ObjectType.GetProperty(OtherProperty);
        if (property == null)
        
            return new ValidationResult(
                string.Format(
                    CultureInfo.CurrentCulture, 
                    "0 is unknown property", 
                    OtherProperty
                )
            );
        
        var otherValue = property.GetValue(validationContext.ObjectInstance, null);
        if (object.Equals(value, otherValue))
        
            return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
        
        return null;
    

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    
        var rule = new ModelClientValidationRule
        
            ErrorMessage = ErrorMessage,
            ValidationType = "notequalto",
        ;
        rule.ValidationParameters["other"] = OtherProperty;
        yield return rule;
    

然后在模型上:

public class MyViewModel

    public string Prop1  get; set; 

    [NotEqual("Prop1", ErrorMessage = "should be different than Prop1")]
    public string Prop2  get; set; 

控制器:

public class HomeController : Controller

    public ActionResult Index()
    
        return View(new MyViewModel
        
            Prop1 = "foo",
            Prop2 = "foo"
        );
    

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    
        return View(model);
    

并查看:

@model MyViewModel

<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
<script type="text/javascript">
    jQuery.validator.unobtrusive.adapters.add(
        'notequalto', ['other'], function (options) 
            options.rules['notEqualTo'] = '#' + options.params.other;
            if (options.message) 
                options.messages['notEqualTo'] = options.message;
            
    );

    jQuery.validator.addMethod('notEqualTo', function(value, element, param) 
        return this.optional(element) || value != $(param).val();
    , '');
</script>

@using (Html.BeginForm())

    <div>
        @Html.LabelFor(x => x.Prop1)
        @Html.EditorFor(x => x.Prop1)
        @Html.ValidationMessageFor(x => x.Prop1)
    </div>
    <div>
        @Html.LabelFor(x => x.Prop2)
        @Html.EditorFor(x => x.Prop2)
        @Html.ValidationMessageFor(x => x.Prop2)
    </div>
    <input type="submit" value="OK" />

【讨论】:

像魅力一样工作,但您提供的解决方案不能使用 ErrorMessageResourceType 和 ErrorMessageResourceName。你可以使用类似的东西:errorMessage = new ResourceManager(ErrorMessageResourceType).GetString(ErrorMessageResourceName); 很好的答案,非常有助于让我在正确的轨道上做一些自定义验证器。 我很好奇如何使用来自资源的错误消息。 Rookian所说的不是常量表达式,所以不能用在属性中。此解决方案devtrends.co.uk/blog/… 适用于资源错误消息,但我看不出区别。我认为视图消息没有正确连接? 它适用于 EditorFor,但不适用于 DropDownList。它不会生成数据验证消息。知道我该怎么做吗?【参考方案2】:

是的,这是正确的方法。您应该实现自己的属性并实现IClientValidatable

您还可以将所需的布尔值最初设置为 false 作为隐藏表单字段。当用户更改文本框时,将其设置为 true。

【讨论】:

【参考方案3】:

您可以让您的 ViewModel 实现 IValidatableObject,并在实现 Validate 方法(来自 IValidatableObject)时添加一些逻辑来检查属性的值,例如

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 
        var results = new List<ValidationResult>();

        if (Name == "Please enter your name...") 
            results.Add(new ValidationResult("You must enter a name");

        ...
        Enter other validation here
        ...     

        return results;
    

现在,当在您的控制器中调用 Model.IsValid 时,该部分逻辑将运行并正常返回验证错误。

【讨论】:

【参考方案4】:

你的问题被问到已经过了一段时间,但如果你仍然喜欢数据注释,这个问题可以使用this library轻松解决:

[Required]
[AssertThat("FieldA != 'some text'")]
public string FieldA  get; set; 

上面,字段值与一些预定义的文本进行比较。或者,您可以相互比较字段值:

[AssertThat("FieldA != FieldB")]

...当被比较的字符串的大小写无关紧要时:

[AssertThat("CompareOrdinalIgnoreCase(FieldA, FieldB) != 0")]

【讨论】:

【参考方案5】:

为了改进@Darin Dimitrov 的答案,如果您想使用ErrorMessageResourceName and ErrorMessageResourceType 从资源中添加消息,只需将其添加到错误消息ErrorMessage = ErrorMessage ?? ErrorMessageString

ErrorMessageString 将查找您使用这些参数(ErrorMessageResourceName 和 ErrorMessageResourceType)在模型中设置的错误消息的本地化版本

【讨论】:

【参考方案6】:

理想的解决方案是自定义属性,您可以在其中指定最小和最大长度以及 MustNotContain="请输入您的姓名..."。

【讨论】:

我真的不明白这个答案与这里所问的有什么关系,即如何验证视图模型上的两个属性不相等。 我将问题解读为 - 我如何知道名称字段包含有效名称,而不是默认值“请输入您的姓名”。这种性质的验证可以使用一个非常通用的属性来执行,该属性可以用于许多领域。

以上是关于mvc3 验证输入“不等于”的主要内容,如果未能解决你的问题,请参考以下文章

在进入系统之前必须输入两次登录凭据 - MVC3

js 金额输入判断 大于0.01 不等于0

MVC 3/4 Intranet 应用程序自动/使用 Chrome 的静默身份验证

struts2如何验证文本框大于0但不等于0

Jquery 验证不能正确验证数字?

使用 Lightspeed 进行 MVC3 验证