2012-02-21 11 views
38

फायरिंग नहीं मेरे पास है निम्नलिखित नियमविनीत ग्राहक सत्यापन fluentvalidation और asp.net MVC के का उपयोग कर LessThanOrEqualTo

1 विनीत, ग्राहक साइड सत्यापन का उपयोग कर काम करता है, दूसरा नहीं

किसी भी विचार क्यों?

RuleFor(x => x.StartDate) 
    .LessThanOrEqualTo(x => x.EndDate.Value) 
    .WithLocalizedMessage(() => CommonRes.Less_Than_Or_Equal_To, filters => CommonRes.Start_Date, filters => CommonRes.End_Date); 

RuleFor(x => x.StartDate) 
    .GreaterThanOrEqualTo(x => x.AbsoluteStartDate) 
    .LessThanOrEqualTo(x => x.AbsoluteEndDate) 
    .WithLocalizedMessage(() => CommonRes.Between, filters => CommonRes.Start_Date, filters => filters.AbsoluteStartDate, filters => filters.AbsoluteEndDate); 
+0

क्या आप वाकई पहले काम करते हैं? 'LessThanOrEqualTo' क्लाइंट सत्यापन द्वारा समर्थित होने के रूप में [प्रलेखन] (http://fluentvalidation.codeplex.com/wikipage?title=mvc&referringTitle=Documentation) में सूचीबद्ध नियमों में से एक नहीं है। आप किस एफवी का उपयोग कर रहे हैं? –

+0

ओह आदमी !! यह 'LessThanOrEqualTo' था इसके लिए कोई काम है? – iwayneo

उत्तर

75

LessThanOrEqualTo या GreaterThanOrEqualTo नियमों का न तो ग्राहक साइड सत्यापन के द्वारा समर्थित हैं के रूप में documentation में विस्तार से बताया।

इसका मतलब यह है कि अगर आप उनके लिए ग्राहक साइड सत्यापन करना चाहते हैं आप एक कस्टम FluentValidationPropertyValidator लिखने और GetClientValidationRules विधि है जो आप एक कस्टम एडाप्टर रजिस्टर करने की अनुमति देगा को लागू करने और जावास्क्रिप्ट में इसके लिए ग्राहक साइड सत्यापन तर्क को लागू करने की आवश्यकता होगी ।

यदि आप रुचि रखते हैं कि यह कैसे प्राप्त किया जा सकता है तो मुझे बस पिंग करें और मैं एक उदाहरण प्रदान करूंगा।


अद्यतन:

अनुरोध के रूप में, मैं कैसे एक LessThanOrEqualTo शासन के लिए कस्टम ग्राहक साइड सत्यापन को लागू कर सकता का एक उदाहरण दिखाने का प्रयास करेगा। यह गैर-निरर्थक तिथियों के साथ केवल एक विशेष मामला है। सभी संभावित मामलों के लिए ऐसे कस्टम क्लाइंट साइड वैलिडेटर को लिखना निश्चित रूप से संभव है लेकिन इसके लिए काफी अधिक प्रयासों की आवश्यकता होगी।

तो हम एक दृश्य के मॉडल और एक इसी सत्यापनकर्ता के साथ शुरू:

[Validator(typeof(MyViewModelValidator))] 
public class MyViewModel 
{ 
    [Display(Name = "Start date")] 
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)] 
    public DateTime StartDate { get; set; } 

    public DateTime DateToCompareAgainst { get; set; } 
} 

public class MyViewModelValidator : AbstractValidator<MyViewModel> 
{ 
    public MyViewModelValidator() 
    { 
     RuleFor(x => x.StartDate) 
      .LessThanOrEqualTo(x => x.DateToCompareAgainst) 
      .WithMessage("Invalid start date"); 
    } 
} 

फिर एक नियंत्रक:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     var model = new MyViewModel 
     { 
      StartDate = DateTime.Now.AddDays(2), 
      DateToCompareAgainst = DateTime.Now 
     }; 
     return View(model); 
    } 

    [HttpPost] 
    public ActionResult Index(MyViewModel model) 
    { 
     return View(model); 
    } 
} 

और एक दृश्य:

@model MyViewModel 
@using (Html.BeginForm()) 
{ 
    @Html.Hidden("DateToCompareAgainst", Model.DateToCompareAgainst.ToString("yyyy-MM-dd")) 

    @Html.LabelFor(x => x.StartDate) 
    @Html.EditorFor(x => x.StartDate) 
    @Html.ValidationMessageFor(x => x.StartDate) 
    <button type="submit">OK</button> 
} 
यह सब

मानक सामान है अब तक। यह काम करेगा लेकिन ग्राहक सत्यापन के बिना।

पहला कदम लिखना है FluentValidationPropertyValidator:

public class LessThanOrEqualToFluentValidationPropertyValidator : FluentValidationPropertyValidator 
{ 
    public LessThanOrEqualToFluentValidationPropertyValidator(ModelMetadata metadata, ControllerContext controllerContext, PropertyRule rule, IPropertyValidator validator) 
     : base(metadata, controllerContext, rule, validator) 
    { 
    } 

    public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() 
    { 
     if (!this.ShouldGenerateClientSideRules()) 
     { 
      yield break; 
     } 

     var validator = Validator as LessThanOrEqualValidator; 

     var errorMessage = new MessageFormatter() 
      .AppendPropertyName(this.Rule.GetDisplayName()) 
      .BuildMessage(validator.ErrorMessageSource.GetString()); 

     var rule = new ModelClientValidationRule 
     { 
      ErrorMessage = errorMessage, 
      ValidationType = "lessthanorequaldate" 
     }; 
     rule.ValidationParameters["other"] = CompareAttribute.FormatPropertyForClientValidation(validator.MemberToCompare.Name); 
     yield return rule; 
    } 
} 

जो Application_Start में पंजीकृत किया जाएगा जब हमारे FluentValidation प्रदाता को विन्यस्त:

FluentValidationModelValidatorProvider.Configure(x => 
{ 
    x.Add(typeof(LessThanOrEqualValidator), (metadata, context, rule, validator) => new LessThanOrEqualToFluentValidationPropertyValidator(metadata, context, rule, validator)); 
}); 

और आखिरी बिट ग्राहक पर कस्टम एडाप्टर है ।

<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script> 

और कस्टम अनुकूलक:

(function ($) { 
    $.validator.unobtrusive.adapters.add('lessthanorequaldate', ['other'], function (options) { 
     var getModelPrefix = function (fieldName) { 
      return fieldName.substr(0, fieldName.lastIndexOf(".") + 1); 
     }; 

     var appendModelPrefix = function (value, prefix) { 
      if (value.indexOf("*.") === 0) { 
       value = value.replace("*.", prefix); 
      } 
      return value; 
     } 

     var prefix = getModelPrefix(options.element.name), 
      other = options.params.other, 
      fullOtherName = appendModelPrefix(other, prefix), 
      element = $(options.form).find(":input[name=" + fullOtherName + "]")[0]; 

     options.rules['lessthanorequaldate'] = element; 
     if (options.message != null) { 
      options.messages['lessthanorequaldate'] = options.message; 
     } 
    }); 

    $.validator.addMethod('lessthanorequaldate', function (value, element, params) { 
     var parseDate = function (date) { 
      var m = date.match(/^(\d{4})-(\d{1,2})-(\d{1,2})$/); 
      return m ? new Date(parseInt(m[1]), parseInt(m[2]) - 1, parseInt(m[3])) : null; 
     }; 

     var date = parseDate(value); 
     var dateToCompareAgainst = parseDate($(params).val()); 

     if (isNaN(date.getTime()) || isNaN(dateToCompareAgainst.getTime())) { 
      return false; 
     } 

     return date <= dateToCompareAgainst; 
    }); 

})(jQuery); 
+0

@Iwayneo, ठीक है। मेरे पास पहला सवाल यह है कि क्या आप जिस संपत्ति की तुलना कर रहे हैं वह LessThanOrEqualTo validator में एक समान फ़ील्ड है, यानी आप गतिशील मान के विरुद्ध तुलना कर रहे हैं (जिसे उपयोगकर्ता द्वारा इनपुट क्षेत्र में बदला जा सकता है) या यह है मूल्य यह है कि इस संपत्ति को उस समय देखा गया था जब दृश्य प्रस्तुत किया गया था? –

+0

सत्यापित की जा रही संपत्ति एक फॉर्म फ़ील्ड है - जो प्रवीणता हम तुलना कर रहे हैं वह एक स्थिर गैर-संपादन योग्य फ़ील्ड है जिसे दृश्य प्रस्तुत किया गया था - हम इसे – iwayneo

+0

@Iwayneo रूप में एक छिपे हुए क्षेत्र में संग्रहीत करते हैं, आप मूल्य संग्रहित कर रहे हैं एक छिपे हुए क्षेत्र में तुलना करने के लिए ??? एक मिनट रुकिए। किसी उपयोगकर्ता को उदाहरण के लिए फ़ायरबग का उपयोग करने से रोकने के लिए जो कुछ भी वह चाहता है उसे संशोधित करने के लिए और फिर इनपुट फ़ील्ड में जो भी तारीख चाहता है उसे दर्ज करने से रोकता है और इस प्रकार आपके सर्वर की तरफ से सत्यापन भी छोटा हो जाता है ??? यह आपके आवेदन के लिए एक बड़ा सुरक्षा खतरा है। क्लाइंट से आने वाले मूल्य के विरुद्ध आप संभवतः तुलना कैसे कर सकते हैं (इस मामले में छुपा क्षेत्र लेकिन आसानी से संशोधित)? –

5

डैरिन की मिसाल इसमें कुछ अप्रचलित सामान है इसलिए यहाँ, तो हम निश्चित रूप से 2 स्क्रिप्ट हमारे पेज के लिए आदेश विनीत ग्राहक साइड सत्यापन सक्षम करने के लिए जोड़ने एक और अद्यतन उदाहरण है कि मेरे पास संख्या तुलना है।आप आसानी से तिथि तुलना के लिए यह ठीक कर सकते हैं, हालांकि:

जावास्क्रिप्ट:

(function ($) 
{ 
    $.validator.addMethod("lessthanorequal", function(value, element, param) 
    { 
     return this.optional(element) || parseFloat(value) <= parseFloat(param); 
    }, "Must be less than"); 

    $.validator.unobtrusive.adapters.add("lessthanorequal", ["field"], function (options) 
    { 
     options.rules["lessthanorequal"] = options.params.field; 
     if (options.message) options.messages["lessthanorequal"] = options.message; 
    }); 
})(jQuery); 

सी #

public class LessThanOrEqualPropertyValidator : FluentValidationPropertyValidator 
{ 

    public LessThanOrEqualPropertyValidator(ModelMetadata metadata, ControllerContext controllerContext, PropertyRule rule, IPropertyValidator validator) 
     : base(metadata, controllerContext, rule, validator) 
    { 
    } 

    public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() 
    { 
     if (!ShouldGenerateClientSideRules()) yield break; 

     var formatter = new MessageFormatter().AppendPropertyName(Rule.PropertyName); 
     string message = formatter.BuildMessage(Validator.ErrorMessageSource.GetString()); 
     var rule = new ModelClientValidationRule 
     { 
      ValidationType = "lessthanorequal", 
      ErrorMessage = message 
     }; 

     rule.ValidationParameters["field"] = ((LessThanOrEqualValidator)Validator).ValueToCompare; 
     yield return rule; 
    } 
} 

Global.asax Application_Start:

FluentValidation.Mvc.FluentValidationModelValidatorProvider.Configure(x => 
{ 
    x.Add(typeof(LessThanOrEqualValidator), (metadata, context, description, validator) => new LessThanOrEqualPropertyValidator(metadata, context, description, validator)); 
}); 

तो अब LessThanOrEqual का उपयोग करने वाले किसी भी संख्या नियम को ग्राहक पक्ष मान्य किया जाएगा।

+0

क्लाइंट साइड सत्यापन अच्छी तरह से चल रहा है, लेकिन त्रुटि संदेश अच्छी तरह से नहीं है '' खरीद दिनांक '' {ComparisonValue} 'से कम या उसके बराबर होना चाहिए।' – Willy

+0

दिनांक प्रारूप समस्या भी है, मैं डीडी/एमएम/yyyy पैटर्न का उपयोग कर रहा हूँ, उदाहरण के लिए वर्तमान दिनांक 20/10/2014 है। अगर मैं 15/10/2014 भरता हूं, तो यह 'खरीद ऑर्डरडेट' प्रदर्शित करेगा '{ComparisonValue}' से कम या उसके बराबर होना चाहिए। ' – Willy

संबंधित मुद्दे