我有一個StartMate和一個EndDate的ViewModel。很明顯,我需要驗證StartDate < = EndDate。MVC3服務器驗證沒有觸發
我創建了StartDateBeforeEndDate
驗證屬性,並飾以它的ViewModel類:
public class ValidProgramDisplayStartDateAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
ProgramCreateOrEditViewModel vm = value as ProgramCreateOrEditViewModel;
if (vm == null) return true; //not our problem
if (!vm.EndDisplay.HasValue) return true;
//if you don't set an end date, you can't be invalid
return vm.StartDisplay <= vm.EndDisplay;
}
}
...
[ValidProgramDisplayStartDate(ErrorMessage="The program start display date cannot be after the program display end date.")]
public class ProgramCreateOrEditViewModel
{
[Required(ErrorMessage = "A program title is required.")]
[StringLength(255, ErrorMessage = "The program title cannot exceed 255 characters.")]
public virtual string Title { get; set; }
private DateTime _startDisplayDate = DateTime.Now;
[Display(Name = "Display Start Date")]
[Required(ErrorMessage = "A start display date is required")]
[DataType(DataType.Date)]
public virtual DateTime StartDisplay { get { return _startDisplayDate; } set { _startDisplayDate = value; } }
[Display(Name="Display End Date")]
[DataType(DataType.Date)]
public virtual DateTime? EndDisplay { get; set; }
...more properties omitted...
}
標題是正確有效的,並顯示在驗證摘要作爲其確認消息預期的,但IsValid上的斷點不會觸發,並且如果給出無效配對,則不會出現驗證錯誤。
ValidationAttribute
在創建ViewModel對象,填充日期,創建ValidationAttribute
對象並調用其IsValid
方法的單元測試中正常工作。如果我在Controller中的POST操作上設置斷點,並且使用Visual Studio的立即窗口構造ValidationAttribute
並將它傳遞給接收的ViewModel,它也可以正常工作。
我並不在乎這個階段的客戶端驗證,那是在「很高興有,但誰有時間」下提交的?然而,服務器端驗證至關重要。
查看:
@model MyProject.Web.Mvc.Controllers.ViewModels.ProgramCreateOrEditViewModel
@using MvcContrib.FluentHtml
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
@using (Html.BeginForm())
{
<fieldset class="program"><legend>Program</legend>
@if (!ViewData.ModelState.IsValid)
{
<p class="error">Please correct all errors listed below. The program cannot be saved while errors remain.</p>
@Html.ValidationSummary(false)
}
@Html.HiddenFor(m => m.Id)
<h3>
@Html.LabelFor(m => m.Title)
@Html.TextBoxFor(m => m.Title)</h3>
<div id="accordion">
<h3><a href="#">Dates:</a></h3>
<div class="section">
Dates related to <em>displaying</em> the program on our site:<br />
@Html.LabelFor(m => m.StartDisplay)
@Html.EditorFor(m => m.StartDisplay, new { _class = "date" })
@Html.LabelFor(m => m.EndDisplay)
@Html.EditorFor(m => m.EndDisplay, new { _class = "date enddisplay" })
</div>
... more form fields omitted ...
</div>
<p>
<input type="submit" value="Save" /></p>
</fieldset>
}
最後,編輯模板:
@model DateTime?
@Html.TextBox("", Model.HasValue ? Model.Value.ToString("MM/dd/yyyy") : String.Empty, new { @class = "date" })
你有沒有檢查過,如果你需要UnobtrusiveJavaScript它被啓用? – stack72
我沒有打擾過這條路,但是我完全關心服務器端,如果JavaScript對我的服務器端驗證有影響,今天我需要更多的咖啡因。 :) –