问题描述
我使用FluentValidation,我想用一些对象的属性值的格式的消息。现在的问题是我有在C#中的前pressions和代表们非常缺乏经验。
I am using FluentValidation and I want to format a message with some of the object's properties value. The problem is I have very little experience with expressions and delegates in C#.
FluentValidation已经提供了一种与格式参数做到这一点。
FluentValidation already provides a way to do this with format arguments.
RuleFor(x => x.Name).NotEmpty()
.WithMessage("The name {1} is not valid for Id {0}", x => x.Id, x => x.Name);
我愿做这样的事情,以避免更改消息字符串,如果我更改参数的顺序。
I would like to do something like this to avoid having to change the message string if I change the order of the parameters.
RuleFor(x => x.Name).NotEmpty()
.WithMessage("The name {Name} is not valid for Id {Id}",
x => new
{
Id = x.Id,
Name = x.Name
});
原来的方法签名如下所示:
The original method signature looks like this:
public static IRuleBuilderOptions<T, TProperty> WithMessage<T, TProperty>(
this IRuleBuilderOptions<T, TProperty> rule, string errorMessage,
params Func<T, object>[] funcs)
我在想提供这种方法与函数功能的列表。
I was thinking of providing this method with a list of Func.
任何人都可以帮助我?
推荐答案
您不能做到这一点,在FluentValidation的WithMessage但你可以高插孔CustomState财产和有注入你的消息。这里是一个工作的例子;你的另一个选择是到餐桌FluentValidation并进行额外的过载为WithMethod。
You can't do that with the WithMessage in FluentValidation but you can high-jack the CustomState property and inject your message there. Here is a working example; Your other option is to fork FluentValidation and make an additional overload for the WithMethod.
这是从这个博客帖子的控制台应用程序从的NuGet引用FluentValidation和JamesFormater:
This is a console application with references to FluentValidation from Nuget and the JamesFormater from this blog post:
http://haacked.com/archive/2009/01/04/fun-with-named-formats-string-parsing-and-edge-cases.aspx
的最佳答案。拿了灵感来自伊利亚,实现你可以捎带过一口流利验证的扩展方法本质。这样的在下面的工作原理,而不需要修改在库中的任何强>
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
using FluentValidation;
namespace stackoverflow.fv
{
class Program
{
static void Main(string[] args)
{
var target = new My() { Id = "1", Name = "" };
var validator = new MyValidator();
var result = validator.Validate(target);
foreach (var error in result.Errors)
Console.WriteLine(error.ErrorMessage);
Console.ReadLine();
}
}
public class MyValidator : AbstractValidator<My>
{
public MyValidator()
{
RuleFor(x => x.Name).NotEmpty().WithNamedMessage("The name {Name} is not valid for Id {Id}");
}
}
public static class NamedMessageExtensions
{
public static IRuleBuilderOptions<T, TProperty> WithNamedMessage<T, TProperty>(
this IRuleBuilderOptions<T, TProperty> rule, string format)
{
return rule.WithMessage("{0}", x => format.JamesFormat(x));
}
}
public class My
{
public string Id { get; set; }
public string Name { get; set; }
}
public static class JamesFormatter
{
public static string JamesFormat(this string format, object source)
{
return FormatWith(format, null, source);
}
public static string FormatWith(this string format
, IFormatProvider provider, object source)
{
if (format == null)
throw new ArgumentNullException("format");
List<object> values = new List<object>();
string rewrittenFormat = Regex.Replace(format,
@"(?<start>\{)+(?<property>[\w\.\[\]]+)(?<format>:[^}]+)?(?<end>\})+",
delegate(Match m)
{
Group startGroup = m.Groups["start"];
Group propertyGroup = m.Groups["property"];
Group formatGroup = m.Groups["format"];
Group endGroup = m.Groups["end"];
values.Add((propertyGroup.Value == "0")
? source
: Eval(source, propertyGroup.Value));
int openings = startGroup.Captures.Count;
int closings = endGroup.Captures.Count;
return openings > closings || openings % 2 == 0
? m.Value
: new string('{', openings) + (values.Count - 1)
+ formatGroup.Value
+ new string('}', closings);
},
RegexOptions.Compiled
| RegexOptions.CultureInvariant
| RegexOptions.IgnoreCase);
return string.Format(provider, rewrittenFormat, values.ToArray());
}
private static object Eval(object source, string expression)
{
try
{
return DataBinder.Eval(source, expression);
}
catch (HttpException e)
{
throw new FormatException(null, e);
}
}
}
}
这篇关于使用FluentValidation的WithMessage方法命名参数列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!