2011-04-11 1 views
1

유효성 검사 유형이 고유해야하므로 여러 정규식 패턴을 사용하여 클라이언트 측의 유효성 검증을 사용하여 속성을 검증 할 방법이 없으므로 다음을 수행 할 수 있도록 FluentValidation을 확장하기로 결정했습니다.클라이언트 측 유효성 검사를 위해 ErrorMessage 전달

RuleFor(x => x.Name).NotEmpty().WithMessage("Name is required") 
        .Length(3, 20).WithMessage("Name must contain between 3 and 20 characters") 
        .Match(@"^[A-Z]").WithMessage("Name has to start with an uppercase letter") 
        .Match(@"^[a-zA-Z0-9_\-\.]*$").WithMessage("Name can only contain: a-z 0-9 _ - .") 
        .Match(@"[a-z0-9]$").WithMessage("Name has to end with a lowercase letter or digit") 
        .NotMatch(@"[_\-\.]{2,}").WithMessage("Name cannot contain consecutive non-alphanumeric characters"); 



내가 알아 내야 마지막 것은 그래서 온 "데이터 Val으로부터 customregex [SOMEFANCYSTRINGHERETOMAKEITUNIQUE]"의 속성을 끝낸다 GetClientValidationRules() 통해 WithMessage()하여 설정된 ErrorMessage가 전달하는 방법이다 입력 요소.

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { 
    var rule = new ModelClientValidationRule(); 
    rule.ErrorMessage = [INSERT ERRORMESSAGE HERE]; 
    rule.ValidationType = "customregex" + StringFunctions.RandomLetters(6); 
    rule.ValidationParameters.Add("pattern", pattern); 

    yield return rule; 
} 


은 내가 FluentValidation의 소스 코드에서 찾아 봤는데,하지만 그것을 알아낼 수 없었다. 누구든지 아이디어가있어?

답변

2

내가 제레미 스키너 (의 창조자로이 작업을 수행하는 방법을 논의했습니다를 Fluent Validation)
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); 
    } 
} 
,617 :

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 :
자바 스크립트 jQuery.validator을 wireup하기 :

실제로
(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)); 
1

약간의 주제는 있지만 어쩌면 도움이 될 수 있습니다. 정규식은 매우 강력합니다, 당신은 하나의 정규식에있는 모든 규칙을 결합 생각해 봤어? 그 이유는 regex 유효성 검사를 제공하는 속성은 대개 속성 당 여러 인스턴스를 허용하지 않는 이유입니다.

당신 그래서 예를 들면

, 당신의 정규식은 다음과 같습니다

"^[A-Z]([a-zA-Z0-9][_\-\.]{0,1}[a-zA-Z0-9]*)*[a-z0-9]$" 

그리고 그것을 테스트 할 수있는 편리한 장소 : http://derekslager.com/blog/posts/2007/09/a-better-dotnet-regular-expression-tester.ashx

+0

내가, 내가 처음에 무엇을했다 먹으 렴 있지만 나는 정확하게 무엇이 잘못되었는지를 설명하는 상세한 오류 메시지를 사용자에게 제공하여 어떻게 수정해야 하는지를 설명하고자한다. – Fabian

+0

맞아. 여기서 또 다른 일은 사용자 정의 유효성 검사입니다. 그런 다음 모든 정규식을 평가하고 원하는 오류 메시지를 제공 할 수 있습니다. 무엇보다도, 당신은 기본 MVC 프레임 워크를 벗어날 필요가 없습니다 : [CustomValidation (typeof (MyValidator), "MyCombinedRegexNameValidation")] – Milimetric

+0

그럴 수도 있지만 더 쉽게 여러 속성에 사용할 수있는 더 나은 솔루션을 찾고 있습니다./모델과 나중에 심지어 정확한 javascript 파일을 사용하여 validator clientside를 첨부합니다. – Fabian