使用FluentValidation的WithMessage方法和命名参数列表我正在使用FluentValidation,我想为一个对象的属性值格式化一条消息。问题是我对C#中的表达式和委托的经验很少。FluentValidation已经提供了一种使用格式参数执行此操作的方法。RuleFor(x=>x.Name).NotEmpty().WithMessage("名称{1}对于ID{0}无效",x=>x.Id,x=>x.Name);我想做这样的事情以避免在更改参数顺序时更改消息字符串。RuleFor(x=>x.Name).NotEmpty().WithMessage("名称{Name}对于Id{Id}无效",x=>new{Id=x.Id,Name=x.Name});原始方法签名如下所示:publicstaticIRuleBuilderOptionsWithMessage(thisIRuleBuilderOptionsrule,stringerrorMessage,paramsFunc[]funcs)我想给这个方法一个Func列表。有人可以帮我弄这个吗?您不能使用FluentValidation中的WithMessage执行此操作,但您可以提升JackState属性并在其中注入您的消息。这是一个工作示例;您的另一个选择是分叉FluentValidation并为WithMethod进行额外的重载。这是一个控制台应用程序,它从这篇博文中引用了Nuget和JamesFormater的FluentValidation:http://haacked.com/archive/2009/01/04/fun-with-named-formats-string-parsing-and-edge-cases。aspx最佳答案。从Ilya那里获得灵感并意识到您可以利用流畅验证的扩展方法本质。因此,以下工作无需修改库中的任何内容。使用系统;使用System.Collections.Generic;使用System.Text.RegularExpressions;使用System.Web;使用System.Web.UI;使用FluentValidation;namespacestackoverflow.fv{classProgram{staticvoidMain(string[]args){vartarget=newMy(){Id="1",Name=""};varvalidator=newMyValidator();varresult=validator.Validate(target);foreach(varerrorinresult.Errors)Console.WriteLine(error.ErrorMessage);控制台.ReadLine();}}publicclassMyValidator:AbstractValidator{publicMyValidator(){RuleFor(x=>x.Name).NotEmpty().WithNamedMessage("名称{Name}对Id{Id}无效");}}publicstaticclassNamedMessageExtensions{publicstaticIRuleBuilderOptionsWithNamedMessage(这个IRuleBuilderOptions规则,字符串格式){returnrule.WithMessage("{0}",x=>format.JamesFormat(x));}}publicclassMy{publicstringId{get;放;}公共字符串名称{得到;放;}}公共静态类JamesFormatter{公共staticstringJamesFormat(thisstringformat,objectsource){returnFormatWith(format,null,source);}publicstaticstringFormatWith(thisstringformat,IFormatProviderprovider,objectsource){if(format==null)thrownewArgumentNullException("format");列表值=newList();stringrewrittenFormat=Regex.Replace(format,@"(?{)+(?[w.[]]+)(?:[^}]+)?(?})+",delegate(Matchm){组startGroup=m.Groups["start"];GrouppropertyGroup=m.Groups["property"];GroupformatGroup=m.Groups["format"];GroupendGroup=m.Groups["end"];values.Add((propertyGroup.Value=="0")?source:Eval(source,propertyGroup.Value));intopenings=startGroup.Captures.Count;intclosings=endGroup.Captures.Count;返回开口>关闭||开口%2==0?m.Value:newstring('{',openings)+(values.Count-1)+formatGroup.Value+newstring('}',closings);},RegexOptions.Compiled|RegexOptions.CultureInvariant|RegexOptions.IgnoreCase);退役urnstring.Format(provider,rewrittenFormat,values.ToArray());}privatestaticobjectEval(objectsource,stringexpression){try{returnDataBinder.Eval(source,expression);}catch(HttpExceptione){thrownewFormatException(null,e);}}}}在C#6.0中,这大大简化了现在你可以这样做(有点hack,但比分支Fluentvalidation好得多):RuleFor(x=>x.Name).NotEmpty().WithMessage("{0}",x=>$"名称{x.Name}对ID{x.Id}无效。");太糟糕了,他们没有提供WithMessage重载接受Alambda接受对象,你可以这样做:RuleFor(x=>x.Name).NotEmpty().WithMessage(x=>$"Thename{x.Name}对Id{x.Id}无效。");我认为他们试图复制string.Format本身是为了实现更短的语法是愚蠢的,但最终却降低了灵活性,以至于我们无法干净利落地使用新的C#6.0语法。虽然KhalidAbuhakmeh的回答非常好且有深度,但我只想分享一个解决这个问题的简单方法。如果您害怕位置参数,为什么不使用连接运算符+来封装错误创建机制并利用需要Func的WithMessage重载。这个CustomerValidatorpublicclassCustomerValidator:AbstractValidator{publicCustomerValidator(){RuleFor(customer=>customer.Name).NotEmpty().WithMessage("{0}",CreateErrorMessage);}privatestringCreateErrorMessage(Customerc){return"Thename"+c.Name+"isnotvalidforId"+c.Id;}}在下一个片段中打印正确的原始错误消息:varcustomer=newCustomer(){Id=1,Name=""};varresult=newCustomerValidator().Validate(客户);Console.WriteLine(result.Errors.First().ErrorMessage);或者,使用内联lambda:publicclassCustomerValidator:AbstractValidator{publicCustomerValidator(){RuleFor(customer=>customer.Name).NotEmpty().WithMessage("{0}",c=>"Thename"+c.Name+"对Id无效"+c.Id);}}基于ErikE的答案扩展方法。publicstaticclassRuleBuilderOptionsExtensions{publicstaticIRuleBuilderOptionsWithMessage(这个IRuleBuilderOptionsrule,Funcfunc)=>DefaultValidatorOptions.WithMessage(rule,"{0}",func);publicstaticIRuleBuilderOptionsWithMessage(此IRuleBuilderOptions规则,Funcfunc)=>DefaultValidatorOptions。WithMessage(规则,"{0}",func);}使用示例:以上是C#学习教程:使用FluentValidation的WithMessage方法和命名参数列表,分享所有内容,如果对大家有用,需要进一步了解C#希望大家多多关注教程—RuleFor(_=>_.Name).NotEmpty().WithMessage(_=>$"名称{_.Name}对于ID{_.Id}无效。");RuleFor(_=>_.Value).GreaterThan(0).WithMessage((_,p)=>$"值{p}对Id{_.Id}无效。");本文收集自网络,不代表立场,如涉及侵权,请点击右边联系管理员删除。如需转载请注明出处:
