ฉันประสบปัญหาเดียวกันกับรูปแบบวันที่แบบสั้นที่เชื่อมโยงกับคุณสมบัติของโมเดล DateTime หลังจากดูตัวอย่างต่างๆมากมาย (ไม่เพียง แต่เกี่ยวกับ DateTime) ฉันจึงรวบรวมสิ่งต่อไปนี้:
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;
}
}
}
}
เพื่อให้สอดคล้องกับวิธีการกำหนดเส้นทาง ฯลฯ ในไฟล์ Global ASAX ฉันยังได้เพิ่มคลาส sytatic ใหม่ในโฟลเดอร์ App_Start ของโปรเจ็กต์ MVC4 ของฉันชื่อ 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());
}
}
}
จากนั้นฉันก็โทรไปที่ RegisterCustomModelBinders แบบคงที่จาก Global ASASX Application_Start ของฉันเช่นนี้:
protected void Application_Start()
{
CustomModelBindersConfig.RegisterCustomModelBinders();
}
หมายเหตุสำคัญที่นี่คือถ้าคุณเขียนค่า DateTime ลงใน hiddenfield เช่นนี้:
@Html.HiddenFor(model => model.SomeDate)
@Html.Hiddenfor(model => model)
ฉันทำอย่างนั้นและค่าจริงบนหน้าอยู่ในรูปแบบ "MM / dd / yyyy hh: mm: ss tt" แทนที่จะเป็น "dd / MM / yyyy hh: mm: ss tt" อย่างที่ฉันต้องการ สิ่งนี้ทำให้การตรวจสอบโมเดลของฉันล้มเหลวหรือส่งคืนวันที่ผิด (เห็นได้ชัดว่าการสลับค่าวันและเดือนรอบ ๆ )
หลังจากเกาหัวหลายครั้งและพยายามล้มเหลววิธีแก้ปัญหาคือตั้งค่าข้อมูลวัฒนธรรมสำหรับทุกคำขอโดยทำใน Global.ASAX:
protected void Application_BeginRequest()
{
CultureInfo cInf = new CultureInfo("en-ZA", false);
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;
}
จะไม่ทำงานถ้าคุณติดไว้ใน Application_Start หรือแม้แต่ Session_Start เนื่องจากกำหนดให้กับเธรดปัจจุบันสำหรับเซสชัน อย่างที่คุณทราบกันดีว่าเว็บแอปพลิเคชันไม่มีสถานะดังนั้นเธรดที่ให้บริการคำขอของคุณก่อนหน้านี้จึงไม่ใช่เธรดเดียวกันที่ให้บริการคำขอปัจจุบันของคุณดังนั้นข้อมูลวัฒนธรรมของคุณจึงไปสู่ GC ที่ยอดเยี่ยมในโลกดิจิทัล
ขอบคุณไปที่: Ivan Zlatev - http://ivanz.com/2010/11/03/custom-model-binding-using-imodelbinder-in-asp-net-mvc-two-gotchas/
การิก - https://stackoverflow.com/a/2468447/578208
Dmitry - https://stackoverflow.com/a/11903896/578208