Tôi vẫn còn khá mới với ASP.NET và MVC và mặc dù ngày googling và thử nghiệm, tôi đang vẽ một cách trống tốt nhất để giải quyết vấn đề này .ASP.NET MVC - Bảo toàn lựa chọn DateTime không hợp lệ với 3 danh sách thả xuống
Tôi đã viết một BirthdayAttribute mà tôi muốn làm việc tương tự như EmailAddressAttribute. Thuộc tính sinh nhật đặt gợi ý giao diện người dùng để DateTime sinh nhật sẽ được hiển thị bằng mẫu trình chỉnh sửa có 3 danh sách thả xuống. Thuộc tính này cũng có thể được sử dụng để thiết lập một số dữ liệu meta bổ sung cho biết danh sách thả xuống của năm sẽ hiển thị bao nhiêu năm.
Tôi biết tôi có thể sử dụng bộ chọn ngày của jQuery, nhưng trong trường hợp sinh nhật tôi thấy 3 trình đơn thả xuống dễ sử dụng hơn nhiều.
@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>")
Tôi cũng có ModelBinder để xây dựng lại ngày của mình sau đó. Tôi đã loại bỏ nội dung của các hàm trợ giúp của tôi cho ngắn gọn, nhưng tất cả mọi thứ hoạt động tốt đến thời điểm này. Ngày bình thường, hợp lệ, hoạt động tốt để tạo hoặc chỉnh sửa thành viên của tôi.
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
}
}
Bây giờ tôi đang xem nó, có lẽ tôi nên sử dụng DateTime không có giá trị, nhưng đó không phải ở đây cũng không có ở đó.
Sự cố tôi gặp phải là xác thực rất cơ bản các ngày không hợp lệ như ngày 30 tháng 2 hoặc ngày 31 tháng 9. Việc xác nhận chính nó hoạt động tốt, nhưng ngày không hợp lệ không bao giờ được lưu và tồn tại khi biểu mẫu được tải lại.
Điều tôi muốn là nhớ ngày không hợp lệ của ngày 30 tháng 2 và hiển thị lại nó bằng thông báo xác thực thay vì đặt lại danh sách thả xuống về giá trị mặc định của họ. Các trường khác, như địa chỉ email (được trang trí với thuộc tính EmailAddressAttribute) bảo vệ các mục không hợp lệ tốt khỏi hộp.
Hiện tại, tôi chỉ đang cố gắng để xác thực phía máy chủ hoạt động. Thành thật mà nói, tôi thậm chí không bắt đầu suy nghĩ về việc xác nhận phía khách hàng được nêu ra.
Tôi biết có rất nhiều điều tôi có thể làm với javascript và ajax để làm cho vấn đề này trở thành điểm tranh luận, nhưng tôi vẫn muốn có xác thực hợp lệ phía máy chủ để quay trở lại.
nếu bạn thêm sự kiện thay đổi vào menu thả xuống, bạn có thể tạo ngày đầy đủ trong trường bị ẩn và xác thực điều này, sau đó có thể chọn lại giá trị trong menu thả xuống từ giá trị hộp văn bản ẩn. mã phía máy khách – davethecoder