【问题标题】:ASP.Net Core MVC - Client-side validation for custom attributeASP.Net Core MVC - 自定义属性的客户端验证
【发布时间】:2016-04-12 07:48:35
【问题描述】:

在以前版本的 MVC 框架中,自定义验证将通过实现 IClientValidatableGetClientValidationRules 方法来实现。

然而,在 ASP.Net Core MVC we do not have this interface 中,虽然我们确实有 IClientModelValidator,它定义了一个非常相似的方法。然而,它的实现永远不会被调用。

那么 - 我们如何为 ASP.NET Core MVC 中的自定义属性实现客户端验证?

【问题讨论】:

    标签: c# asp.net validation asp.net-core asp.net-core-mvc


    【解决方案1】:

    IClientModelValidator 实际上是正确的接口。我在下面做了一个人为的示例实现。

    注意: RC1 和 RC2 之间的IClientModelValidator 接口有一个breaking change。下面介绍了这两个选项 - 两个版本之间的其余代码相同。

    属性(RC2 及以上)

    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
    public sealed class CannotBeRedAttribute : ValidationAttribute, IClientModelValidator
    {
        public override bool IsValid(object value)
        {
            var message = value as string;
            return message?.ToUpper() == "RED";
        }
    
        public void AddValidation(ClientModelValidationContext context)
        {
            MergeAttribute(context.Attributes, "data-val", "true");
            var errorMessage = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
            MergeAttribute(context.Attributes, "data-val-cannotbered", errorMessage);
        }
    
        private bool MergeAttribute(
            IDictionary<string, string> attributes,
            string key,
            string value)
        {
            if (attributes.ContainsKey(key))
            {
                return false;
            }
            attributes.Add(key, value);
            return true;
        }
    }
    

    属性(RC1)

    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
    public sealed class CannotBeRedAttribute : ValidationAttribute, IClientModelValidator
    {
        public override bool IsValid(object value)
        {
            var message = value as string;
            return message?.ToUpper() == "RED";
        }
    
        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(
            ClientModelValidationContext context)
        {
            yield return new ModelClientValidationRule(
                "cannotbered",
                FormatErrorMessage(ErrorMessage));
        }
    }
    

    型号

    public class ContactModel
    {
        [CannotBeRed(ErrorMessage = "Red is not allowed!")]
        public string Message { get; set; }
    }
    

    查看

    @model WebApplication22.Models.ContactModel
    
    <form asp-action="Contact" method="post">
        <label asp-for="Message"></label>
        <input asp-for="Message" />
        <span asp-validation-for="Message"></span>
        <input type="submit" value="Save" />
    </form>
    
    @section scripts {
        <script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
        <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
        <script>
            $.validator.addMethod("cannotbered",
                function (value, element, parameters) {
                    return value.toUpperCase() !== "RED";
                });
    
            $.validator.unobtrusive.adapters.add("cannotbered", [], function (options) {
                options.rules.cannotbered = {};
                options.messages["cannotbered"] = options.message;
            });
        </script>
    }
    

    【讨论】:

    • 我已经完全按照您在示例中所示的方式完成了。但它不起作用,它没有显示 GetClientValidationRules 返回的消息。而是显示默认的必需消息?
    • @Rohit 我的示例中的自定义属性只有在输入框中输入“red”字样时才会显示错误。
    • 感谢您的帮助。那行得通。但是,如何从 GetClientValidationRules 方法返回我的自定义消息。我不想在模型属性上指定 [CannotBeRed(ErrorMessage = "Not red!")]
    • 我编写了一个类,我从中获取自定义错误消息,我想在“GetClientValidationRules”方法中使用这些错误消息。如果我像 yield return new ModelClientValidationRule( "cannotbered", FormatErrorMessage(MyClass.GetCustomMessage('somekey')); 那样这样做,它会将默认的必填字段消息显示为“消息字段是必需的”。你能帮忙吗?
    • @Rohit 在我的示例中从Message 属性中删除[Required] 属性。这就是为您提供默认所需消息的原因。至于下拉自定义消息,我会推荐this SO question。它应该对 ASP.NET Core 仍然有效。
    猜你喜欢
    • 2014-11-03
    • 2013-11-12
    • 1970-01-01
    • 2020-11-15
    • 2018-07-02
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    • 2014-03-19
    相关资源
    最近更新 更多