mvc3 验证输入“不等于”

发布于 2024-11-03 00:43:49 字数 315 浏览 0 评论 0原文

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

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

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

谢谢

My forms have inputs with default helper text that guides the user on what to enter (rather than using labels). This makes validation tricky because the input value is never null.

How can I extend unobtrusive validation to handle this? The form shouldn't be valid if the Name input is equal to "Please enter your name..."

I started reading Brad Wilson's blog post on validation adapters, but I'm not sure if this is the right way to go? I need to be able to validate against different default values depending on the field.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

度的依靠╰つ 2024-11-10 00:43:49

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

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

Here's a sample illustrating how you could proceed to implement a custom validation attribute:

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

and then on the model:

public class MyViewModel
{
    public string Prop1 { get; set; }

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

controller:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new MyViewModel
        {
            Prop1 = "foo",
            Prop2 = "foo"
        });
    }

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

and view:

@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" />
}
感情废物 2024-11-10 00:43:49

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

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

Yes thats the right way to go. You should implement your own atribute and implement IClientValidatable.

You could also have a required boolean value set initially to false as a hidden form field. When the user changes the textbox, set it to true.

断肠人 2024-11-10 00:43:49

您可以使 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 时,将运行这段逻辑并将返回验证错误正常。

You could make your ViewModel implement IValidatableObject and when implementing the Validate method (from IValidatableObject) add some logic to check the values of the properties e.g.

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

Now, when Model.IsValid is called in your controller, this bit of logic will be ran and will return validation errors as normal.

活雷疯 2024-11-10 00:43:49

自从提出你的问题以来花了一点时间,但如果你仍然喜欢数据注释,这个问题可以使用 this 轻松解决库

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

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

[AssertThat("FieldA != FieldB")]

...并且当比较的字符串的大小写不重要时:

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

It took a little while since your question was asked, but if you still like data annotations, this problem can be easily solved using this library:

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

Above, the field value is compared with some pre-defined text. Alternatively, you can compare fields values with each other:

[AssertThat("FieldA != FieldB")]

...and when the case of the strings being compared does not matter:

[AssertThat("CompareOrdinalIgnoreCase(FieldA, FieldB) != 0")]
北方的巷 2024-11-10 00:43:49

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

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

To improve a little bit of @Darin Dimitrov answer, if you want to add messages from the resources using ErrorMessageResourceName and ErrorMessageResourceType, just add this to the to the Error message ErrorMessage = ErrorMessage ?? ErrorMessageString

The ErrorMessageString will look for the localized version of error message that you set in the model using those parameters (ErrorMessageResourceName and ErrorMessageResourceType)

青朷 2024-11-10 00:43:49

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

The ideal solutions is a custom Attribute where you specify minimum and maximum lengths as well as MustNotContain="Please enter your name...".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文