Tôi đã gặp vấn đề tương tự với định dạng ngày ngắn ràng buộc với các thuộc tính mô hình DateTime. Sau khi xem xét nhiều ví dụ khác nhau (không chỉ liên quan đến DateTime), tôi kết hợp các follwing:
using System;
using System.Globalization;
using System.Web.Mvc;
namespace YourNamespaceHere
{
public class CustomDateBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (controllerContext == null)
throw new ArgumentNullException("controllerContext", "controllerContext is null.");
if (bindingContext == null)
throw new ArgumentNullException("bindingContext", "bindingContext is null.");
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (value == null)
throw new ArgumentNullException(bindingContext.ModelName);
CultureInfo cultureInf = (CultureInfo)CultureInfo.CurrentCulture.Clone();
cultureInf.DateTimeFormat.ShortDatePattern = "dd/MM/yyyy";
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, value);
try
{
var date = value.ConvertTo(typeof(DateTime), cultureInf);
return date;
}
catch (Exception ex)
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex);
return null;
}
}
}
public class NullableCustomDateBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (controllerContext == null)
throw new ArgumentNullException("controllerContext", "controllerContext is null.");
if (bindingContext == null)
throw new ArgumentNullException("bindingContext", "bindingContext is null.");
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (value == null) return null;
CultureInfo cultureInf = (CultureInfo)CultureInfo.CurrentCulture.Clone();
cultureInf.DateTimeFormat.ShortDatePattern = "dd/MM/yyyy";
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, value);
try
{
var date = value.ConvertTo(typeof(DateTime), cultureInf);
return date;
}
catch (Exception ex)
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex);
return null;
}
}
}
}
Để theo cách các tuyến đường v.v. được ghi lại trong tệp ASAX toàn cầu, tôi cũng đã thêm một lớp sytatic mới vào thư mục App_Start của dự án MVC4 của tôi có tên CustomModelBinderConfig:
using System;
using System.Web.Mvc;
namespace YourNamespaceHere
{
public static class CustomModelBindersConfig
{
public static void RegisterCustomModelBinders()
{
ModelBinders.Binders.Add(typeof(DateTime), new CustomModelBinders.CustomDateBinder());
ModelBinders.Binders.Add(typeof(DateTime?), new CustomModelBinders.NullableCustomDateBinder());
}
}
}
Sau đó, tôi chỉ cần gọi RegisterCustomModelBinder tĩnh từ Ứng dụng ASASX toàn cầu của mình_Start như thế này:
protected void Application_Start()
{
/* bla blah bla the usual stuff and then */
CustomModelBindersConfig.RegisterCustomModelBinders();
}
Một lưu ý quan trọng ở đây là nếu bạn viết giá trị DateTime vào một trường ẩn như thế này:
@Html.HiddenFor(model => model.SomeDate) // a DateTime property
@Html.Hiddenfor(model => model) // a model that is of type DateTime
Tôi đã làm điều đó và giá trị thực tế trên trang là ở định dạng "MM / dd / yyyy hh: mm: ss tt" thay vì "dd / MM / yyyy hh: mm: ss tt" như tôi muốn. Điều này khiến xác thực mô hình của tôi không thành công hoặc trả về ngày sai (rõ ràng là hoán đổi giá trị ngày và tháng xung quanh).
Sau nhiều nỗ lực gãi đầu và thất bại, giải pháp là đặt thông tin văn hóa cho mọi yêu cầu bằng cách thực hiện điều này trong Global.ASAX:
protected void Application_BeginRequest()
{
CultureInfo cInf = new CultureInfo("en-ZA", false);
// NOTE: change the culture name en-ZA to whatever culture suits your needs
cInf.DateTimeFormat.DateSeparator = "/";
cInf.DateTimeFormat.ShortDatePattern = "dd/MM/yyyy";
cInf.DateTimeFormat.LongDatePattern = "dd/MM/yyyy hh:mm:ss tt";
System.Threading.Thread.CurrentThread.CurrentCulture = cInf;
System.Threading.Thread.CurrentThread.CurrentUICulture = cInf;
}
Nó sẽ không hoạt động nếu bạn dán nó vào Application_Start hoặc thậm chí Session_Start vì điều đó gán nó cho luồng hiện tại cho phiên. Như bạn đã biết, các ứng dụng web là không trạng thái, do đó, luồng phục vụ yêu cầu của bạn trước đó là cùng một luồng phục vụ yêu cầu hiện tại của bạn do đó thông tin văn hóa của bạn đã chuyển sang GC tuyệt vời trên bầu trời kỹ thuật số.
Cảm ơn, hãy truy cập: Ivan Zlatev - http://ivanz.com/2010/11/03/custom-model-binding-USE-imodelbinder-in-asp-net-mvc-two-gotchas/
garik - https://stackoverflow.com/a/2468447/578208
Dmitry - https://stackoverflow.com/a/11903896/578208