2011-08-21 64 views
0

我有一個ViewModel將Date,Hour和minute保存爲一個字符串,每個都有一個用於輸入值的文本框, want是一個自定義的驗證器,可以確保如果一個值被輸入到其中一個字段中,那麼其餘的都必須填寫,否則它們可能是空的,它的全部或沒有!如何使用2個參數(Asp.net mvc 3)獲取我的自定義驗證工作(Asp.net mvc 3)

我在這裏做了一個小測試項目,但它沒有按照它應該的方式工作,我遵循http://www.devtrends.co.uk/blog/the-complete-guide-to-validation-in-asp.net-mvc-3-part-2,但我認爲我的問題是客戶端,因爲我無法在Params上看到任何值,如果我在chrome中執行斷點。

的觀點:

@model validationproject.Models.DateTimeViewModel 

@{ 
    ViewBag.Title = "ViewPage1"; 
} 

<script src="../../Scripts/jquery-1.5.1.min.js" type="text/javascript"></script> 
<script src="../../Scripts/jquery.unobtrusive-ajax.min.js" type="text/javascript"></script> 
<script src="../../Scripts/jquery.validate.min.js" type="text/javascript"></script> 
<script src="../../Scripts/jquery.validate.unobtrusive.min.js" type="text/javascript"></script> 
<script src="../../Scripts/Validators.js" type="text/javascript"></script> 

<h2>ViewPage1</h2> 
@using (Ajax.BeginForm("CreateDateTime", "Home", new {}, new AjaxOptions {HttpMethod = "Post"})) 
{ 
    <span> 
    @Html.TextBoxFor(model => model.Date, new {@Id = "date"}) 

    @Html.TextBoxFor(model => model.Hour, new {@Id = "hour"}) 

    @Html.TextBoxFor(model => model.Minute, new {@Id = "minute"}) 

    @Html.ValidationMessageFor(model => model.Date) 
    @Html.ValidationMessageFor(model => model.Hour) 
    @Html.ValidationMessageFor(model => model.Minute) 
    </span> 
} 

JQuery的驗證文件

$.validator.unobtrusive.adapters.add(
      'fulldaterequired', 
      ['part1', 'part2'], 
      function (options) { 
       options.rules['fulldaterequiredcheck'] = options.params; 
       options.messages['fulldaterequiredcheck'] = options.message; 
      } 
     ); 

$.validator.addMethod(
     'fulldaterequiredcheck', 
     function (value, element, params) { 

      if (!value && (params['otherproperty1'] || params['otherproperty2'])) { 
       return false; 
      } 
      return true; 
     } 
    ); 

我的視圖模型

using System; 
using System.Collections.Generic; 
using System.ComponentModel.DataAnnotations; 
using System.Web.Mvc; 

namespace validationproject.Models 
{ 
    public class DateTimeViewModel 
    { 
     [Display(Name = "Date")] 
     [FullDateRequired(("Hour"), ("Minute"))] 
     public string Date { get; set; } 

     [Display(Name = "Hour")] 
     [FullDateRequired(("Minute"), ("Date"))] 
     public string Hour { get; set; } 

     [Display(Name = "Minute")] 
     [FullDateRequired(("Hour"), ("Date"))] 
     public string Minute { get; set; } 
    } 

    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] 
    public sealed class FullDateRequired : ValidationAttribute, IClientValidatable 
    { 
     private const string DefaultErrorMessage = "{0} is required."; 
     public string OtherProperty1 { get; private set; } 
     public string OtherProperty2 { get; private set; } 
     public FullDateRequired(string otherProperty1, string otherProperty2) 
      : base(DefaultErrorMessage) 
     { 
      OtherProperty1 = otherProperty1; 
      OtherProperty2 = otherProperty2; 
     } 
     public override string FormatErrorMessage(string name) 
     { 
      return string.Format(ErrorMessageString, name); 
     } 
     protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
     { 
      var otherProperty1 = validationContext.ObjectInstance.GetType().GetProperty(OtherProperty1); 
      var otherProperty2 = validationContext.ObjectInstance.GetType().GetProperty(OtherProperty2); 
      var otherProperty1Value = string.IsNullOrEmpty((string)otherProperty1.GetValue(validationContext.ObjectInstance, null)); 
      var otherProperty2Value = string.IsNullOrEmpty((string)otherProperty2.GetValue(validationContext.ObjectInstance, null)); 

      if (string.IsNullOrEmpty((string)value) && (!otherProperty1Value || !otherProperty2Value)) 
      { 
       return new ValidationResult(FormatErrorMessage(validationContext.DisplayName)); 
      } 
      return ValidationResult.Success; 
     } 
     public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
     { 
      var clientValidationRule = new ModelClientValidationRule() 
      { 
       ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()), 
       ValidationType = "fulldaterequired" 
      }; 
      clientValidationRule.ValidationParameters.Add("otherproperty1", OtherProperty1); 
      clientValidationRule.ValidationParameters.Add("otherproperty2", OtherProperty2); 
      return new[] { clientValidationRule }; 
     } 
    } 
} 

回答

1

您的JavaScript中包含 '第1部分' 和 '第2部分',這應該是 'otherproperty1' 和'你的viewmodel中定義的'otherproperty2'。正確的腳本應該是:

$.validator.unobtrusive.adapters.add(
     'fulldaterequired', 
     ['otherproperty1', 'otherproperty2'], 
     function (options) { 
      options.rules['fulldaterequiredcheck'] = options.params; 
      options.messages['fulldaterequiredcheck'] = options.message; 
     } 
    ); 

     $.validator.addMethod(
    'fulldaterequiredcheck', 
    function (value, element, params) { 
     if (value == '' && ($('#' + params['otherproperty1']).val() != '' || $('#' + params['otherproperty2']).val() != '')) { 
      return false; 
     } 
     return true; 
    } 
); 

添加到您的視圖(表單內)展示errormessages當你按下提交鍵:

@Html.ValidationMessageFor(model => model.Date) 
    @Html.ValidationMessageFor(model => model.Hour) 
    @Html.ValidationMessageFor(model => model.Minute) 

    <input type="submit" /> 
+0

現在已經改變了一些代碼,但如果我在任何類型我的3個文本框中的一個向類添加了「有效」類,但沒有添加到應該失敗的類中?所以那些沒有文本的人(其他文本域有文本應該失敗) – Mech0z

+0

編輯答案,改變fulldaterequiredcheck的邏輯,現在應該工作 –

+0

再次編輯,犯了一個錯誤。 –