如何在FluentValidation中创建警告消息 [英] How to create warning messages in FluentValidation

查看:87
本文介绍了如何在FluentValidation中创建警告消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I would like to add style to the validation messages based on enum type. FluentValidation offers possibility to add custom state for messages by using WithState method. Depending on which enum is used it would add a class for that message in HTML, so later I could add styling to it.

模型验证器类:

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 添加到每个错误消息中.因此,我想需要以某种方式覆盖该逻辑.

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

I noticed that ASP.NET MVC is using unobtrusive.js by default and adding class .field-validation-error to each error message. So I guess needs to override that logic somehow.

How can I add styles to validation messages depending on provided enum type?

推荐答案

我弄清楚了如何实现这一点.首先需要创建一个HTML帮助器,该帮助器将构建html标签并向其中添加必要的类.此帮助程序允许针对一个字段/属性显示具有不同类型的多个消息.

很棒的文章解释了如何做到这一点,可能是那里唯一的一篇!

I figured out how to implement this. First need to create a html helper that will build the html tags and add necessary classes to them. This helper allows to display multiple messages with different types for one field/property.

Great article that explains how to do it, possibly the only one out there!
http://www.pearson-and-steel.co.uk/

HTML Helper方法

Html Helper method

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

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

Also, inside controller action method need to get validator errors and store them inside a session.

控制器操作方法

Controller action method

// 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帮助器即可.

And simply use that html helper inside view.

查看

View

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

    ...
}

仅当遍历列表时,才需要最后一个索引参数.

The last index parameter is required only if looping through lists.

这篇关于如何在FluentValidation中创建警告消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆