Передача данных из пользовательского атрибута проверки на страницу / представление - PullRequest
1 голос
/ 14 апреля 2020

Допустим, у меня есть собственный атрибут проверки:

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} приведет к локализованному имени члена свойства. Но поскольку мы передали пользовательскую строку ошибки в адаптер, для нее будет установлено пользовательское сообщение об ошибке.

Возможно, она немного грязная, но она выполняет свою работу.

1 Ответ

1 голос
/ 14 апреля 2020

Вы не можете передать его обратно. Все, что установлено в атрибуте, является stati c, потому что атрибуты создаются на месте, т.е. там нет возможности что-либо изменить там позже. Как правило, сообщение об ошибке передается в виде строки формата («Это недопустимо: {0}»), и затем код проверки будет использовать его вместе с чем-то вроде string.Format для заполнения имени члена.

Локализация не является проблемой, о которой должен беспокоиться атрибут. Вам просто нужно добавить локализатор аннотаций данных:

services.AddControllers()
    .AddDataAnnotationsLocalization();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...