我一直在討論如何與傑里米·斯金納(創造者這樣做流利的驗證)在
http://fluentvalidation.codeplex.com/discussions/253505
他很友善地寫一個完整的例子。
更新
這是我們想出了代碼:
首先擴展,對於比賽和NotMatch。
public static class Extensions
{
public static IRuleBuilderOptions<T, string> Match<T>(this IRuleBuilder<T, string> ruleBuilder, string expression)
{
return ruleBuilder.SetValidator(new MatchValidator(expression));
}
public static IRuleBuilderOptions<T, string> NotMatch<T>(this IRuleBuilder<T, string> ruleBuilder, string expression) {
return ruleBuilder.SetValidator(new MatchValidator(expression, false));
}
}
用於驗證
public interface IMatchValidator : IPropertyValidator
{
string Expression { get; }
bool MustMatch { get; }
}
所使用的接口的實際驗證:
public class MatchValidatorAdaptor : FluentValidationPropertyValidator
{
public MatchValidatorAdaptor(ModelMetadata metadata, ControllerContext controllerContext, PropertyRule rule, IPropertyValidator validator)
: base(metadata, controllerContext, rule, validator)
{
}
IMatchValidator MatchValidator
{
get { return (IMatchValidator)Validator; }
}
public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
{
var formatter = new MessageFormatter().AppendPropertyName(Rule.PropertyDescription);
string errorMessage = formatter.BuildMessage(Validator.ErrorMessageSource.GetString());
yield return new ModelClientValidationMatchRule(MatchValidator.Expression, MatchValidator.MustMatch, errorMessage);
}
}
:
public class MatchValidator : PropertyValidator, IMatchValidator
{
string expression;
bool mustMatch;
public MatchValidator(string expression, bool mustMatch = true)
: base(string.Format("The value {0} match with the given expression, while it {1}.", mustMatch ? "did not" : "did", mustMatch ? "should" : "should not"))
{
this.expression = expression;
this.mustMatch = mustMatch;
}
protected override bool IsValid(PropertyValidatorContext context)
{
return context.PropertyValue == null ||
context.PropertyValue.ToString() == string.Empty ||
Regex.IsMatch(context.PropertyValue.ToString(), expression) == mustMatch;
}
public string Expression
{
get { return expression; }
}
public bool MustMatch {
get { return mustMatch; }
}
}
註冊驗證的適配器
最後神奇在哪裏發生了:
public class ModelClientValidationMatchRule : ModelClientValidationRule
{
public ModelClientValidationMatchRule(string expression, bool mustMatch, string errorMessage)
{
if (mustMatch)
base.ValidationType = "match";
else
base.ValidationType = "notmatch";
base.ValidationType += StringFunctions.RandomLetters(6);
base.ErrorMessage = errorMessage;
base.ValidationParameters.Add("expression", expression);
}
}
更新2:
Javascript來wireup jQuery.validator:
(function ($) {
function attachMatchValidator(name, mustMatch) {
$.validator.addMethod(name, function (val, element, expression) {
var rg = new RegExp(expression, "gi");
return (rg.test(val) == mustMatch);
});
$.validator.unobtrusive.adapters.addSingleVal(name, "expression");
}
$("input[type=text]").each(function() {
$.each(this.attributes, function (i, attribute) {
if (attribute.name.length == 20 && attribute.name.substring(0, 14) == "data-val-match")
attachMatchValidator(attribute.name.substring(9, 20), true);
if (attribute.name.length == 23 && attribute.name.substring(0, 17) == "data-val-notmatch")
attachMatchValidator(attribute.name.substring(9, 23), false);
});
});
} (jQuery));
事實上,我有這就是我曾在第一,但我想爲我的用戶提供一個詳細的錯誤信息,說明究竟是什麼錯誤,因此他們需要如何解決它。 – Fabian 2011-04-11 21:00:44
對,有道理。這裏要做的另一件事就是自定義驗證。然後,您可以評估所有正則表達式並提供所需的任何錯誤消息。最重要的是,你不必走出基本的mvc框架:[CustomValidation(typeof(MyValidator),「MyCombinedRegexNameValidation」)] – Milimetric 2011-04-11 21:20:01
這可以工作,但即時通訊尋找更好的解決方案,我可以很容易地使用多個屬性/模型,甚至後來甚至使用完全相同的JavaScript文件來附加驗證器clientside的項目。 – Fabian 2011-04-12 07:58:20