如何在ASP.NET MVC验证过程中提供警告? [英] How to provide warnings during validation in ASP.NET MVC?

查看:108
本文介绍了如何在ASP.NET MVC验证过程中提供警告?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有时用户输入是不严格无效,但可以认为是有问题的。

Sometimes user input is not strictly invalid but can be considered problematic.

例如:


  • 用户输入一个单行名称字段一个长句子。的他也许应该
    已经使用了说明字段,而不是

  • 用户输入名称这是非常类似于现有的实体。的也许他输入相同的实体,但并没有意识到它已经存在,或者一些并发用户刚刚进入它。

  • A user enters a long sentence in a single-line Name field. He probably should have used the Description field instead.
  • A user enters a Name that is very similar to that of an existing entity. Perhaps he's inputting the same entity but didn't realize it already exists, or some concurrent user has just entered it.

有些可以很容易地进行检查客户端,有些需要服务器端检查。

Some of these can easily be checked client-side, some require server-side checks.

什么是最好的办法,也许类似于 DataAnnotations 验证的东西,以提供警告,在这种情况下,用户?这里的关键是,用户必须能够覆盖警告和仍然提交表单(或重新提交表单,取决于实现)。

What's the best way, perhaps something similar to DataAnnotations validation, to provide warnings to the user in such cases? The key here is that the user has to be able to override the warning and still submit the form (or re-submit the form, depending on the implementation).

这想到的最可行的解决方案是创建一些属性,类似于 CustomValidationAttribute ,这可能使一个AJAX调用,并会显示一些警告的文本​​,但没有按' ŧ影响的ModelState 。预期的用法是这样的:

The most viable solution that comes to mind is to create some attribute, similar to a CustomValidationAttribute, that may make an AJAX call and would display some warning text but doesn't affect the ModelState. The intended usage is this:

[WarningOnFieldLength(MaxLength = 150)]
[WarningOnPossibleDuplicate()]
public string Name { get; set; }

在该视图:

@Html.EditorFor(model => model.Name)
@Html.WarningMessageFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)

所以,任何想法?

So, any ideas?

推荐答案

总体设计

要开始,我相信你会以某种方式跟踪,如果用户选择忽略该警告。一个简单而透明的方式做到这一点是有一个的忽略警告的复选框,哪些用户会检查提交之前。另一种选择是让他们提交表单的两倍,而忽略第二的警告提交;那么你可能需要的 IgnoreWarnings 的隐藏字段。可能有其它的设计,但为了简单起见,我会与第一个选项去

To start with, I believe you would have to track somehow if the user choose to ignore the warnings. A simple and transparent way to do that is to have an Ignore Warnings check-box, which user would have to check before submit. Another option is a have them submit the form two times and ignore the warnings on the second submit; then you'd probably need an IgnoreWarnings hidden field. There could be other designs, but for the sake of simplicity I'll go with the first option.

在总之,方法是创建


  • 所有视图模型支持验证的预警类型的定制数据注解属性;

  • 一个已知的基类,它的观点车型将继承;

  • 我们将不得不重复的逻辑在JavaScript中每个自定义属性。

请注意,下面的code正好说明了办法,我必须承担相当多的东西不知道完整的上下文。

Please note that the code below just illustrates the approach and I have to assume quite a lot of things without knowing the full context.

视图模型

在这种情况下,最好一个视图模型从实际模型这是一个很好的主意分开。一种可能的方法是有支持的警告所有视图模型的基类:

In this scenario it's best to separate a view model from an actual model which is a good idea anyway. One possible approach is to have a base class for all view models which support warnings:

public abstract class BaseViewModel
{
    public bool IgnoreWarnings { get; set; }
}

一个模型需要单独的关键原因是,有一个在存储在数据库中的 IgnoreWarnings 属性没有什么意义。

您导出视图模型,然后将如下所示:

Your derived view model will then look as follows:

public class YourViewModel : BaseViewModel
{
    [Required]
    [StringLengthWarning(MaximumLength = 5, ErrorMessage = "Your Warning Message")]
    public string YourProperty { get; set; }
}

StringLengthWarning 是服务器和客户端验证的自定义数据注解属性。它只是支持的最大长度,并且可以很容易地与任何其他必要的属性扩展

StringLengthWarning is a custom data annotation attribute for server and client-side validation. It just supports the maximum length and can easily be extended with any other necessary properties.

数据注解属性

属性的核心是的IsValid(价值,validationContext 方法。

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class StringLengthWarningAttribute : ValidationAttribute, IClientValidatable 
{
    public int MaximumLength { get; set; }

    public override bool IsValid(object value)
    {
        return true;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var model = validationContext.ObjectInstance as BaseViewModel;
        var str = value as string;
        if (!model.IgnoreWarnings && (string.IsNullOrWhiteSpace(str) || str.Length > MaximumLength))
            return new ValidationResult(ErrorMessage);
        return base.IsValid(value, validationContext);
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        yield return new StringLengthWarningValidationRule(MaximumLength, ErrorMessage);
    }
}

属性工具 IClientValidatable 并利用自定义客户端验证规则:

The attribute implements IClientValidatable and utilizes a custom client validation rule:

public class StringLengthWarningValidationRule : ModelClientValidationRule
{
    public StringLengthWarningValidationRule(int maximumLength, string errorMessage)
    {
        ErrorMessage = errorMessage;
        ValidationType = "stringlengthwarning";
        ValidationParameters.Add("maximumlength", maximumLength);
        ValidationParameters.Add("ignorewarningsfield", "IgnoreWarnings");
    }
}

客户端JavaScript

最后,使其工作,你需要从视图中引用下面的JavaScript:

Finally, to make it work, you'll need the following JavaScript referenced from your view:

$(function () {
    $.validator.addMethod('stringlengthwarning', function (value, element, params) {
        var maximumlength = params['maximumlength'];
        var ignorewarningsfield = params['ignorewarningsfield'];

        var ctl = $("#" + ignorewarningsfield);
        if (ctl == null || ctl.is(':checked'))
            return true;
        return value.length <= maximumlength;
    });

    $.validator.unobtrusive.adapters.add("stringlengthwarning", ["maximumlength", "ignorewarningsfield"], function (options) {
        var value = {
            maximumlength: options.params.maximumlength,
            ignorewarningsfield: options.params.ignorewarningsfield
        };
        options.rules["stringlengthwarning"] = value;
        if (options.message) {
            options.messages["stringlengthwarning"] = options.message;
        }
    });

}(jQuery));

中的JavaScript做了一些假设您可能要重新审视(该复选框的名字,等等)。

The JavaScript makes some assumptions you might want to revisit (the check-box name, etc).

更新:HTML助手

要为错误和警告分别显示的验证消息,一对夫妇的助手将是必要的。下面的类提供了一个示例:

To display the validation messages separately for errors and warnings, a couple of helpers will be necessary. The following class provides a sample:

public static class  MessageHelpers
{
    public static MvcHtmlString WarningMessageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
    {
        if (htmlHelper.ViewData.ModelState["IgnoreWarnings"] != null)
            return htmlHelper.ValidationMessageFor(expression);
        return MvcHtmlString.Empty;
    }

    public static MvcHtmlString ErrorMessageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
    {
        if (htmlHelper.ViewData.ModelState["IgnoreWarnings"] == null)
            return htmlHelper.ValidationMessageFor(expression);
        return MvcHtmlString.Empty;
    }
}

在视图它们可以照常使用

In the view they can be used as usual:

        @Html.EditorFor(model => model.YourProperty)
        @Html.ErrorMessageFor(model => model.YourProperty)
        @Html.WarningMessageFor(model => model.YourProperty)

这篇关于如何在ASP.NET MVC验证过程中提供警告?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆