對於ASP.NET和MVC,我還是比較新的,儘管數日來一直在使用Google和實驗,但我在解決此問題的最佳方法上留下了一片空白。ASP.NET MVC-使用3個下拉列表保留無效的DateTime選擇
我寫了一個BirthdayAttribute,我想工作類似於EmailAddressAttribute。生日屬性設置UI提示,以便使用具有3個下拉列表的編輯器模板呈現生日日期時間。該屬性還可以用來設置一些額外的元數據,告訴年份下拉它應該顯示多少年。
我知道我可以使用jQuery的日期選擇器,但在生日的情況下,我發現3個下拉菜單更有用。
@model DateTime
@using System;
@using System.Web.Mvc;
@{
UInt16 numberOfVisibleYears = 100;
if (ViewData.ModelMetadata.AdditionalValues.ContainsKey("NumberOfVisibleYears"))
{
numberOfVisibleYears = Convert.ToUInt16(ViewData.ModelMetadata.AdditionalValues["NumberOfVisibleYears"]);
}
var now = DateTime.Now;
var years = Enumerable.Range(0, numberOfVisibleYears).Select(x => new SelectListItem { Value = (now.Year - x).ToString(), Text = (now.Year - x).ToString() });
var months = Enumerable.Range(1, 12).Select(x => new SelectListItem{ Text = new DateTime(now.Year, x, 1).ToString("MMMM"), Value = x.ToString() });
var days = Enumerable.Range(1, 31).Select(x => new SelectListItem { Value = x.ToString("00"), Text = x.ToString() });
}
@Html.DropDownList("Year", years, "<Year>")/
@Html.DropDownList("Month", months, "<Month>")/
@Html.DropDownList("Day", days, "<Day>")
我也有一個ModelBinder來重建我的日期。爲了簡潔起見,我已經刪除了幫助函數的內容,但是到目前爲止,一切都很順利。正常,有效的日期,適用於創建或編輯我的成員。
public class DateSelector_DropdownListBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (controllerContext == null)
throw new ArgumentNullException("controllerContext");
if (bindingContext == null)
throw new ArgumentNullException("bindingContext");
if (IsDropdownListBound(bindingContext))
{
int year = GetData(bindingContext, "Year");
int month = GetData(bindingContext, "Month");
int day = GetData(bindingContext, "Day");
DateTime result;
if (!DateTime.TryParse(string.Format("{0}/{1}/{2}", year, month, day), out result))
{
//TODO: SOMETHING MORE USEFUL???
bindingContext.ModelState.AddModelError("", string.Format("Not a valid date."));
}
return result;
}
else
{
return base.BindModel(controllerContext, bindingContext);
}
}
private int GetData(ModelBindingContext bindingContext, string propertyName)
{
// parse the int using the correct value provider
}
private bool IsDropdownListBound(ModelBindingContext bindingContext)
{
//check model meta data UI hint for above editor template
}
}
現在我正在看它,我應該使用一個可爲空的DateTime,但這不是在這裏也不在那裏。
我遇到的問題是非常基本的無效日期驗證,如2月30日或9月31日。驗證本身效果很好,但無效日期不會在表單重新加載時保存和保存。
我想要記住2月30日的無效日期,並用驗證消息重新顯示它,而不是將下拉列表重置爲默認值。其他字段,例如電子郵件地址(用EmailAddressAttribute裝飾)可以保留無效的條目,就像開箱即用。
此刻,我只是試圖讓服務器端驗證工作。說實話,我還沒有開始考慮客戶端驗證。
我知道有很多我可以用javascript和ajax來做這個問題的一個爭論點,但我寧願有適當的服務器端驗證到位回落。
如果您將更改事件添加到下拉列表中,您可以在隱藏字段中創建完整日期並驗證它,然後可以從隱藏文本框值中重新選擇下拉列表中的值,但是這樣做並且會客戶端代碼 – davethecoder