2012-02-21 34 views
38

tôi có các quy tắc saukhông phô trương xác nhận khách hàng sử dụng fluentvalidation và asp.net MVC LessThanOrEqualTo không bắn

ngày 1 làm việc sử dụng không phô trương, khách hàng xác nhận phía, thứ hai không

bất kỳ ý tưởng tại sao?

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

Bạn có chắc chắn rằng công trình đầu tiên không? 'LessThanOrEqualTo' không phải là một trong các quy tắc được liệt kê trong [tài liệu] (http://fluentvalidation.codeplex.com/wikipage?title=mvc&referringTitle=Documentation) khi được hỗ trợ bởi xác thực ứng dụng khách. Bạn đang sử dụng phiên bản FV nào? –

+0

oh man !! đó là 'LessThanOrEqualTo' có công việc nào cho việc này không? – iwayneo

Trả lời

75

Cả của LessThanOrEqualTo hoặc GreaterThanOrEqualTo quy tắc được hỗ trợ bởi xác nhận phía khách hàng như được giải thích trong documentation. Điều này có nghĩa rằng nếu bạn muốn có xác nhận phía khách hàng cho họ, bạn sẽ cần phải viết một tùy chỉnh FluentValidationPropertyValidator và thực hiện các phương pháp GetClientValidationRules mà sẽ cho phép bạn đăng ký một bộ điều hợp tùy chỉnh và thực hiện logic xác nhận phía khách hàng cho nó trong javascript. Quay lại đầu trang .

Nếu bạn quan tâm về cách thức này có thể đạt được chỉ cần ping tôi và tôi sẽ cung cấp một ví dụ.


UPDATE:

Như yêu cầu, tôi sẽ cố gắng để hiển thị một ví dụ về cách người ta có thể thực hiện xác nhận phía khách hàng tùy chỉnh cho sự cai trị LessThanOrEqualTo. Nó chỉ là một trường hợp cụ thể với những ngày không có giá trị. Viết trình duyệt tính hợp lệ của phía khách hàng tùy chỉnh cho tất cả các trường hợp có thể là tất nhiên có thể nhưng nó sẽ đòi hỏi nhiều nỗ lực hơn đáng kể.

Vì vậy, chúng ta bắt đầu với một mô hình điểm và một validator tương ứng:

[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"); 
    } 
} 

Sau đó, một bộ điều khiển:

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); 
    } 
} 

và một cái nhìn:

@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> 
} 

Tất cả điều này là công cụ tiêu chuẩn cho đến nay. Nó sẽ hoạt động nhưng không có xác thực ứng dụng khách.

Bước đầu tiên là viết 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; 
    } 
} 

sẽ được đăng ký tại Application_Start khi cấu hình cung cấp FluentValidation của chúng tôi:

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

Và các bit cuối cùng là adapter tùy chỉnh trên máy khách . Vì vậy, chúng ta thêm dĩ nhiên là 2 kịch bản để trang của chúng tôi để cho phép không phô trương xác nhận phía khách hàng:

<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> 

và adapter tùy chỉnh:

(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, OK. Câu hỏi đầu tiên tôi có là thuộc tính bạn so sánh trong trình xác nhận LessThanOrEqualTo có trường tương ứng trong biểu mẫu nghĩa là bạn so sánh với giá trị động (có thể được thay đổi bởi người dùng trong trường nhập) hay nó là giá trị mà thuộc tính này có vào thời điểm xem được hiển thị? –

+0

thuộc tính được xác nhận là trường biểu mẫu - quyền truy cập mà chúng tôi so sánh là trường tĩnh không thể chỉnh sửa được biết thời điểm chế độ xem được hiển thị - chúng tôi lưu trữ nó trong trường ẩn trong biểu mẫu – iwayneo

+0

@iwayneo, bạn đang lưu trữ giá trị để so sánh trong một lĩnh vực ẩn? Đợi tí. Điều gì sẽ ngăn cản người dùng sử dụng FireBug để sửa đổi giá trị của ẩn này thành bất kỳ ngày nào anh ta muốn và sau đó nhập vào bất kỳ ngày nào anh ta muốn trong trường nhập và do đó ngắn mạch ngay cả khi xác thực phía máy chủ của bạn ??? Đó là một mối đe dọa bảo mật rất lớn cho ứng dụng của bạn. Làm thế nào bạn có thể so sánh với một giá trị đến từ khách hàng (trường ẩn trong trường hợp này nhưng dễ dàng sửa đổi)? –

5

dụ Darin của có một số công cụ lỗi thời trong nó, vì vậy đây là một ví dụ cập nhật hơn mà tôi có so sánh số.Bạn có thể dễ dàng tinh chỉnh nó để so sánh ngày mặc dù:

Javascript:

(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); 

C#

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)); 
}); 

Vì vậy, bây giờ bất kỳ quy tắc số nào sử dụng LessThanOrEqual sẽ được xác thực phía máy khách.

+0

Xác thực phía máy khách chạy tốt, nhưng thông báo lỗi không đúng dạng '' PurchaseDate 'phải nhỏ hơn hoặc bằng' {ComparValue} '.' – Willy

+0

Ngoài ra còn có vấn đề định dạng ngày, tôi đang sử dụng mẫu dd/MM/yyyy, ví dụ: ngày hiện tại là 20/10/2014. Nếu tôi điền vào ngày 15/10/2014, nó sẽ hiển thị 'PurchaseOrderDate' phải nhỏ hơn hoặc bằng '{ComparValue}'. ' – Willy

Các vấn đề liên quan