【问题标题】:modelmetadata IsRequired not get rules validation created by FluentValidationmodelmetadata IsRequired 未获取 FluentValidation 创建的规则验证
【发布时间】:2018-04-07 18:59:23
【问题描述】:

我有一个通过 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; }
}

最后是一个用于在@Html.RequiredLabelFor(...) 中覆盖@Html.LabelFor(...) 的htmlhelper 类:

[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));
        }

问题是 LabelHelper 函数中的“metadata.IsRequired”总是返回 false,但它应该为“UserName”属性返回 true.... 我认为这是因为 metadata.IsRequired 无法识别 RegisterValidator 类中的“.NotEmpty()”...

**

有谁知道如何解决这个问题,在 HtmlHelper 上这样做 我可以看看这个属性是“NotEmpty()”,还是通过别的解决方案?

**

【问题讨论】:

    标签: c# asp.net-mvc validation fluentvalidation modelmetadataprovider


    【解决方案1】:

    添加以下标签助手,然后您无需在代码中的任何位置进行更改。只需利用 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);
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      试试 NotNull:

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

      您还可以尝试更易于使用的 DataAnnotations。

      例子:

      [Required]
      string UserName {get; set;}
      

      【讨论】:

      • 我尝试使用.NotNull(),但我得到了相同的结果...如果使用[required] DataAnnotations,我不能同时使用RuleFor 来添加@987654326 @....
      • 使用 FluentValidation 的好处是,例如,我可以创建一次 RegisterValidator 类,并多次将其实现为验证器,然后在我的应用程序中编写一次验证
      猜你喜欢
      • 2011-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-07
      相关资源
      最近更新 更多