【问题标题】:How to create warning messages in FluentValidation如何在 FluentValidation 中创建警告消息
【发布时间】:2016-05-19 11:50:38
【问题描述】:

我想根据枚举类型为验证消息添加样式。 FluentValidation 提供了使用WithState 方法为消息添加自定义状态的可能性。根据使用的枚举,它会在 HTML 中为该消息添加一个类,因此稍后我可以为其添加样式。

模型验证器类:

public class SampleModelValidator : AbstractValidator<SampleModelValidator>
{
    public SampleModelValidator()
    {
        RuleFor(o => o.Age)).NotEmpty()
                // Using custom state here
                .WithState(o => MsgTypeEnum.WARNING)
                .WithMessage("Warning: This field is optional, but better fill it!");
    }
}

控制器动作方法:

[HttpPost]
public ActionResult Submit(SampleModel model)
{
    ValidationResult results = this.validator.Validate(model);
    int warningCount = results.Errors
                .Where(o => o.CustomState?.ToString() == MsgTypeEnum.WARNING.ToString())
                .Count();
    ...
}

我注意到 ASP.NET MVC 默认使用 unobtrusive.js 并将 .field-validation-error 类添加到每个错误消息中。所以我想需要以某种方式覆盖该逻辑。

如何根据提供的枚举类型为验证消息添加样式?

【问题讨论】:

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


    【解决方案1】:

    我想出了如何实现这一点。首先需要创建一个 html 帮助器来构建 html 标记并向它们添加必要的类。此帮助器允许为一个字段/属性显示具有不同类型的多条消息。

    很棒的文章,解释了如何做到这一点,可能是唯一的一篇!
    http://www.pearson-and-steel.co.uk/

    Html Helper 方法

    public static MvcHtmlString ValidationMessageFluent<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, int? itemIndex = null)
    {
        List<ValidationFailure> validationFailures = html.ViewData["ValidationFailures"] as List<ValidationFailure>;
        string exprMemberName = ((MemberExpression)expression.Body).Member.Name;
        var priorityFailures = validationFailures.Where(f => f.PropertyName.EndsWith(exprMemberName));
    
        if (priorityFailures.Count() == 0)
        {
            return null;
        }
    
        // Property name in 'validationFailures' may also be stored like this 'SomeRecords[0].PropertyName'
        string propertyName = itemIndex.HasValue ? $"[{itemIndex}].{exprMemberName}" : exprMemberName;
    
        // There can be multiple messages for one property
        List<TagBuilder> tags = new List<TagBuilder>();
        foreach (var validationFailure in priorityFailures.ToList())
        {
            if (validationFailure.PropertyName.EndsWith(propertyName))
            {
                TagBuilder span = new TagBuilder("span");
                string customState = validationFailure.CustomState?.ToString();
    
                // Handling the message type and adding class attribute
                if (string.IsNullOrEmpty(customState))
                {
                    span.AddCssClass(string.Format("field-validation-error"));
                }
                else if (customState == MsgTypeEnum.WARNING.ToString())
                {
                    span.AddCssClass(string.Format("field-validation-warning"));
                }
    
                // Adds message itself to the html element
                span.SetInnerText(validationFailure.ErrorMessage);
                tags.Add(span);
            }
        }
    
        StringBuilder strB = new StringBuilder();
        // Join all html tags togeather
        foreach(var t in tags)
        {
            strB.Append(t.ToString());
        }
    
        return MvcHtmlString.Create(strB.ToString());
    }
    

    此外,内部控制器操作方法需要获取验证器错误并将它们存储在会话中。

    控制器动作方法

    // In controller you also need to set the ViewData. I don't really like to use itself
    // but did not found other solution
    [HttpPost]
    public ActionResult Submit(SampleModel model)
    {
       IList<ValidationFailure> errors = this.validator.Validate(model).Errors;
       ViewData["ValidationFailures"] = errors as List<ValidationFailure>;
    
        ...
    }
    

    只需在视图中使用该 html 助手。

    查看

    // In html view (using razor syntax)
    @for (int i = 0; i < Model.SomeRecords.Count(); i++)
    {
        @Html.ValidationMessageFluent(o => Model.SomeRecords[i].PropertyName, i)
    
        ...
    }
    

    只有在遍历列表时才需要最后一个索引参数。

    【讨论】:

      猜你喜欢
      • 2012-11-19
      • 1970-01-01
      • 2019-05-17
      • 1970-01-01
      • 1970-01-01
      • 2014-11-23
      • 1970-01-01
      • 1970-01-01
      • 2018-09-16
      相关资源
      最近更新 更多