Не удалось получить метаданные модели IsRequired для проверки правил, созданных FluentValidation

У меня есть класс для создания собственного валидатора от Fluent:

public partial  class RegisterValidator : BaseLarValidator<RegisterModel>
{
   public RegisterValidator(IDbContext dbContext)
     {
        RuleFor(x => x.UserName).NotEmpty().WithMessage("Username obbligatorio");
     }
}

модель класса, которая реализует валидатор RegisterValidator:

[Validator(typeof(RegisterValidator))]
public class RegisterModel
{
public string UserName { get; set; }
}

и, наконец, класс htmlhelper для переопределения @Html.LabelFor(...) в @Html.RequiredLabelFor(...):

[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
        public static MvcHtmlString RequiredLabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object htmlAttributes = null, string id = "", bool generatedId = false)
        {
            return LabelHelper(html, ModelMetadata.FromLambdaExpression(expression, html.ViewData), ExpressionHelper.GetExpressionText(expression), htmlAttributes, id, generatedId);
        }

        internal static MvcHtmlString LabelHelper(HtmlHelper html, ModelMetadata metadata, string htmlFieldName, object htmlAttributes, string id, bool generatedId)
        {
            string labelText = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last();
            if (String.IsNullOrEmpty(labelText))
            {
                return MvcHtmlString.Empty;
            }
            var sb = new StringBuilder();
            sb.Append(labelText);

            if (metadata.IsRequired)
                sb.Append("<span class=\"required\"> *</span>");

            var tag = new TagBuilder("label");

            foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(htmlAttributes))
            {
                tag.MergeAttribute(prop.Name.Replace('_', '-'), prop.GetValue(htmlAttributes).ToString(), true);
            }

            if (!string.IsNullOrWhiteSpace(id))
            {
                tag.Attributes.Add("id", id);
            }
            else if (generatedId)
            {
                tag.Attributes.Add("id", html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName) + "_Label");
            }

            tag.Attributes.Add("for", html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName));
            tag.InnerHtml = sb.ToString();

            return MvcHtmlString.Create(tag.ToString(TagRenderMode.Normal));
        }

Проблема в том, что "metadata.IsRequired" в функции LabelHelper всегда возвращает false, но он должен возвращать true для свойства "UserName".... Я думаю, это происходит потому, что metadata.IsRequired не распознает ".NotEmpty()" в классе RegisterValidator...

**

Кто-нибудь знает, как решить проблему, делая это на HtmlHelper, я могу видеть, является ли свойство "NotEmpty ()", или с помощью другого решения?

**

2 ответа

Добавьте следующий помощник тега, и тогда вам не нужно вносить изменения где-либо в коде. Просто используйте силу DI

[HtmlTargetElement("label", Attributes = ForAttributeName)]
public class LabelRequiredTagHelper : LabelTagHelper
{
    private readonly IValidatorFactory _factory;
    private const string ForAttributeName = "asp-for";

    public LabelRequiredTagHelper(IHtmlGenerator generator, IValidatorFactory factory) : base(generator)
    {
        _factory = factory;
    }

    public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    {
        await base.ProcessAsync(context, output);
        var validator = _factory.GetValidator(For.Metadata.ContainerType);

        var description = validator.CreateDescriptor();
        var propertyValidators = description.GetValidatorsForMember(For.Metadata.PropertyName);
        if (For.Metadata.IsRequired || propertyValidators.Any(p => p is NotNullValidator || p is NotEmptyValidator))
        {
            var sup = new TagBuilder("sup");
            sup.InnerHtml.Append("*");
            output.Content.AppendHtml(sup);
        }
    }
}

Попробуйте NotNull:

RuleFor(x => x.UserName).NotNull().NotEmpty().WithMessage("Username obbligatorio");

Также вы можете попробовать DataAnnotations, которые проще в использовании.

Пример:

[Required]
string UserName {get; set;}
Другие вопросы по тегам