ASP.Net Core MVC - 自定义属性的客户端验证

Posted

技术标签:

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

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

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

那么 - 我们如何为 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 仍然有效。

以上是关于ASP.Net Core MVC - 自定义属性的客户端验证的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET MVC Core/6:多个提交按钮

ASP.NET MVC Core/6:多个提交按钮

使用自定义位置时如何在 asp.net core mvc 中指定视图位置?

ASP.Net Core MVC - 自定义验证

在 ASP.NET Core MVC 中将自定义查询参数添加到操作 URL

asp.net core2 mvc 基础教程--服务注册和管道