首页 > 解决方案 > 将数据从自定义验证属性传递到页面/视图

问题描述

假设我有一个自定义验证属性:

public class CustomAttribute : ValidationAttribute
{
    public override string FormatErrorMessage(string name)
    {
        return string.Format(CultureInfo.CurrentCulture, ErrorMessageString, name);
    }
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {

        var customErrorString = "You did something wrong!"; //How to pass this to the localized string defined in the resource file?

        if(SomethingIsInvalid())
            return new ValidationResult(FormatErrorMessage(validationContext.MemberName));

        return ValidationResult.Success;
    }
}

public class CustomAttributeAdapter : AttributeAdapterBase<CustomAttribute>
{
    public CustomAttributeAdapter(CustomAttribute attribute, IStringLocalizer stringLocalizer)
        : base(attribute, stringLocalizer)
    {
    }

    public override void AddValidation(ClientModelValidationContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        MergeAttribute(context.Attributes, "data-val", "true");
    }

    public override string GetErrorMessage(ModelValidationContextBase validationContext)
    {
        if (validationContext == null)
        {
            throw new ArgumentNullException(nameof(validationContext));
        }

        return GetErrorMessage(validationContext.ModelMetadata, validationContext.ModelMetadata.GetDisplayName());
    }
}

比如说,我如何将数据注释中的字符串传递给验证标签?例如:

[Custom(ErrorMessage = "CustomValidationMessage")]
public string ValidateThis { get; set; }

CustomValidationMessage在资源文件中定义并导致"This is invalid:"

现在我的问题是,如何customErrorString从验证属性传递到本地化字符串,以便它显示在验证标签上,如下所示:

<span id="validation-span" asp-validation-for="@Model.ValidateThis" class="text-danger">This is invalid: You did something wrong!</span>

我希望我的问题很清楚。如果没有,请随时询问更多详细信息。

编辑:我让它工作:

public class CustomAttribute : ValidationAttribute
{
    //Create property to hold our custom error string
    public string CustomErrorString { get; set; }

    public override string FormatErrorMessage(string name)
    {
        return string.Format(CultureInfo.CurrentCulture, ErrorMessageString, name);
    }
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        //Set the custom error string property.
        CustomErrorString = "You did something wrong!"; 

        if(SomethingIsInvalid())
            return new ValidationResult(FormatErrorMessage(validationContext.MemberName));

        return ValidationResult.Success;
    }
}

public class CustomAttributeAdapter : AttributeAdapterBase<CustomAttribute>
{
    //Declare class variable to hold the attribute's custom error string.
    private string _customErrorString = string.empty;

    public CustomAttributeAdapter(CustomAttribute attribute, IStringLocalizer stringLocalizer)
        : base(attribute, stringLocalizer)
    {
        //Set the adapter's custom error string according to the attribute's custom error string
        if(!string.IsNullOrEmpty(attribute.CustomErrorString))
            _customErrorString = attribute.CustomErrorString;
    }

    public override void AddValidation(ClientModelValidationContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        MergeAttribute(context.Attributes, "data-val", "true");
    }

    public override string GetErrorMessage(ModelValidationContextBase validationContext)
    {
        if (validationContext == null)
        {
            throw new ArgumentNullException(nameof(validationContext));
        }

        //Pass the custom error string instead of member name
        return GetErrorMessage(validationContext.ModelMetadata, _customErrorString);
    }
}

完成所有这些之后,您可以像这样设置资源字符串:

[Custom(ErrorMessage = "CustomValidationMessage")]
public string ValidateThis { get; set; }

CustomValidationMessage结果在哪里"This is invalid: {0}"

通常,{0}会导致属性的本地化成员名称。但是因为我们在适配器中传递了自定义的错误字符串,所以会被设置为自定义的错误信息。

它可能有点脏,但它可以完成工作。

标签: asp.net-corevalidationattribute

解决方案


你不能把它传回去。在属性上设置的任何内容都是静态的,因为属性是在适当位置实例化的,即以后没有机会修改那里的任何内容。通常,错误消息将作为格式字符串(“This is invalid: {0}”)传递,然后验证代码将使用它以及诸如string.Format填写成员名称之类的内容。

本地化不是属性需要担心的问题。您只需要添加数据注释本地化器:

services.AddControllers()
    .AddDataAnnotationsLocalization();

推荐阅读