6

我是ASP.Net MVC 3的新手,在嘗試實現客戶端不顯眼的驗證我爲創建自定義日期顯示的編輯器模板時遇到了一些問題辦法。ASP.Net MVC 3 - 客戶端編輯器模板的不顯眼的驗證

UI
我需要在3 texbox UI格式來顯示日期

enter image description here


我提出了一個EditorTemplate用於顯示日期的三個部分

@model DateTime? 

<table class="datetime"> 
<tr> 
    <td>@Html.TextBox("Day", (Model.HasValue ? Model.Value.ToString("dd") : string.Empty)) </td> 
    <td class="separator">/</td> 
    <td>@Html.TextBox("Month", (Model.HasValue ? Model.Value.ToString("MM") : string.Empty))</td> 
    <td class="separator">/</td> 
    <td>@Html.TextBox("Year", (Model.HasValue ? Model.Value.ToString("yyyy") : string.Empty))</td> 
</tr> 
<tr> 
    <td class="label">dd</td> 
    <td/> 
    <td class="label">mm</td> 
    <td/> 
    <td class="label">yyyy</td> 
</tr> 
</table> 

型號
我有權約束出生場的日期是在我的模型,以該物業的子對象的屬性,在這種結構

MyModel 
    --> MySubModel 
      --> DateOfBirth 

public class MySubModel 
{ 
    ... 

    [DataType(DataType.Date)] 
    [Display(Name = "Date of birth")] 
    [DateTimeClientValidation()] 
    public DateTime DateofBirth { get; set; } 

    ... 
} 

客戶端驗證

我已經把一個實現IClientValidatable的自定義驗證屬性設置爲

public class DateTimeClientValidationAttribute : ValidationAttribute, IClientValidatable 
{ 
    ... 

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
    { 
     List<ModelClientValidationRule> clientRules = new List<ModelClientValidationRule>(); 

     //Combined date should be valid 
     ModelClientValidationRule validDateRule = new ModelClientValidationRule 
     { 
      ErrorMessage = "Please enter a valid date.", 
      ValidationType = "validdate" 
     }; 
     validDateRule.ValidationParameters.Add("dayelement", metadata.PropertyName + ".Day"); 
     validDateRule.ValidationParameters.Add("monthelement", metadata.PropertyName + ".Month"); 
     validDateRule.ValidationParameters.Add("yearelement", metadata.PropertyName + ".Year"); 
     clientRules.Add(validDateRule); 

     return clientRules; 
    } 
    ... 
} 

我試圖發佈日期,月&年的文本框到客戶端驗證元素的元素名稱,以便我將在稍後編寫客戶端jquery驗證方法和適配器,它將使用這些元素並進行驗證在客戶端。

查看
現在,使用這個編輯器模板,我把查看以下行

@model MyModel 
... 
<tr> 
    <td class="editor-label"> 
     @Html.LabelFor(m => m.MySubModel.DateofBirth) 
    </td> 
    <td class="editor-field"> 
     @Html.EditorFor(m => m.MySubModel.DateofBirth) 
     @Html.ValidationMessageFor(m => m.MySubModel.DateofBirth) 
    </td> 
</tr> 
... 

添加視圖作爲參考的所有相關jQuery驗證文件

問題

  1. 這不是發射出在HTML中不顯眼的JavaScript驗證屬性,雖然我已經實現IClientValidatable。 出於測試目的,當我把相同的屬性(DateTimeClientValidation)上的另一屬性在未使用該編輯模板的模型,然後將其發射出去的那些驗證特性,它不發射出來僅爲此編輯的模板。我哪裏可能出錯了?
  2. 關於編輯器模板的驗證消息範圍,是正確的,我把它放在View中,還是應該直接放在編輯器模板中(@ Html.ValidationMessageFor(m => m.MySubModel。出生日期)
  3. 在這個例子中,我是正確的設計,我已經把DateTimeClientValidationAttribute,這其實是我把模型的屬性,但這種組件知道一些關於UI(因爲它正試圖散發出一天,月&年的元素名稱給客戶端),這讓模型知道一點關於View,我打破了這裏的任何設計原則?
  4. DateTimeClientValidationAttribute,我試圖發出一天,&年元素名稱給客戶端,以便客戶端腳本可以對其進行驗證。但由於模型屬性出生日期是一個子對象,在腳本中的實際元素名稱是MySubObject.DateOfBirth,這使得日文本框的名稱是MySubObject.DateofBirth.Day,我怎麼能找到完全合格模型名稱GetClientValidationRules方法,這樣我就可以把名字發出給客戶端?

感謝您的耐心閱讀了這一切,併爲答案

回答

9

經過一番努力,我做了控制工作,投入,如果它是有幫助的人在那裏。

第一點是已經控制定義爲

@model DateTime? 

<table class="datetime"> 
<tr> 
    <td>@Html.TextBox("", (Model.HasValue ? Model.Value.ToString("dd") : string.Empty)) </td> 
    <td class="separator">/</td> 
    <td>@Html.TextBox("", (Model.HasValue ? Model.Value.ToString("MM") : string.Empty))</td> 
    <td class="separator">/</td> 
    <td>@Html.TextBox("", (Model.HasValue ? Model.Value.ToString("yyyy") : string.Empty))</td> 
</tr> 
<tr> 
    <td class="label">dd</td> 
    <td/> 
    <td class="label">mm</td> 
    <td/> 
    <td class="label">yyyy</td> 
</tr> 
</table> 

確保,你給空字符串名稱所有三個文本框,這迫使MVC架構產生相應的相同到出生日期爲客戶端的所有三個文本框。此外,列表中的第一個文本框會生成不顯眼的JavaScript驗證參數,因爲它是帶模型名稱的編輯控件的第一次出現。

在客戶端,任何這些文本框上的任何事件都會觸發所有相關的驗證事件,因爲所有這三個文本框都具有相同的名稱。

在定期校驗等所需的頂部,......我們必須寫一個自定義客戶端驗證例程的組合值是否形成有效日期這將結合所有這三個值和檢查。這可以通過Jeff給出的answer來實現。

+0

謝謝!我試圖找出那個問題,正在絞盡腦汁。 – rossisdead 2011-11-17 20:46:52

4

確定這樣幾件事情。首先 - 如果可能的話,不要將日期分成三個字段。你只需將它設置爲一個單獨的字段,並使用jQueryUI的DatePicker,就可以爲自己節約一個頭痛的世界。

接下來,在裏面你DateTimeClientValidationAttribute自定義屬性代碼,你從來沒有真正檢查,看看,如果日期是有效的通過實施的IsValid:

protected override ValidationResult IsValid(object value, 
    ValidationContext validationContext) 
{ 
    ... 
    // Put date parts together and check is valid... 
    if (DateTime.TryParse(year+"/"+month+"/"+day, out dateResult)) 
     return ValidationResult.Success; 

    // Not valid 
    return new ValidationResult(String.Format(ErrorMessageString, 
     validationContext.DisplayName)); 
} 

接下來,您必須創建一個不顯眼的驗證適配器和一個jQuery這使該PARAMS在一起,並試圖解析出日期驗證方法:

jQuery.validator.unobtrusive.adapters.add(
    'validdate', // notice this is coming from how you named your validation rule 
    ['dayelement'], 
    ['monthelement'], 
    ['yearelement'] 
    function (options) { 
     options.rules['datepartcheck'] = options.params; 
     options.messages['datepartcheck'] = options.message; 
    } 
); 
jQuery.validator.addMethod('datepartcheck', function (value, element, params) { 
    var year = params[2]; 
    var month = params[1]; 
    var day = params[0]; 

    var birthDate = year + '/' + month-1 + '/' + day; 
    var isValid = true; 

    try { 
     // datepicker is a part of jqueryUI. 
     // include it and you can take advantage of .parseDate: 
     $.datepicker.parseDate('yy/mm/dd', birthDate); 
    } 
    catch (error) { 
     isValid = false; 
    } 
    return isValid; 
}, ''); 
+0

我的客戶要求推動我分裂日期控制。我有一些管道在不顯眼的jQuery驗證和,使其工作,現在是工作,是啊,你說這是個頭疼的問題。你的答案是最接近的匹配,因此將其標記爲答案。 – Shravan 2011-04-01 08:44:08

相關問題