मैं शॉर्ट डेट फॉर्मेट बाइंडिंग टू डेटटाइम मॉडल प्रॉपर्टीज के साथ एक ही मुद्दा रहा है कई अलग-अलग उदाहरणों को देखने के बाद (न केवल डेटाइम के विषय में) मैंने फोलविंग को एक साथ रखा:
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;
}
}
}
}
ग्लोबल एएसएएक्स फ़ाइल में मार्ग आदि जिस तरह से रजिस्ट्रर्ड हैं, उसके साथ रखने के लिए मैंने अपने MVC4 प्रोजेक्ट के Custom_odelBinderConfig नाम के App_Start फ़ोल्डर में एक नया साइटेटिक क्लास भी जोड़ा है:
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());
}
}
}
मैं तो इस तरह से अपने ग्लोबल ASASX Application_Start से स्थिर RegisterCustomModelBinders कॉल करता हूं:
protected void Application_Start()
{
/* bla blah bla the usual stuff and then */
CustomModelBindersConfig.RegisterCustomModelBinders();
}
यहाँ एक महत्वपूर्ण बात यह है कि यदि आप किसी हिडन फील्ड को डेटटाइम वैल्यू इस तरह लिखते हैं:
@Html.HiddenFor(model => model.SomeDate) // a DateTime property
@Html.Hiddenfor(model => model) // a model that is of type DateTime
मैंने ऐसा किया और पृष्ठ पर वास्तविक मान "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);
// 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;
}
यदि आप इसे Application_Start या Session_Start में चिपकाते हैं तो यह काम नहीं करेगा क्योंकि यह सत्र के लिए वर्तमान थ्रेड को असाइन करता है। जैसा कि आप अच्छी तरह से जानते हैं, वेब एप्लिकेशन स्टेटलेस होते हैं, इसलिए जो धागा आपके अनुरोध को सेवित करता है, वह वही धागा होता है जो आपके वर्तमान अनुरोध को प्रदान करता है इसलिए आपकी संस्कृति की जानकारी डिजिटल आकाश में महान GC में चली गई है।
धन्यवाद पर जाएं: इवान ज़्लाटेव - http://ivanz.com/2010/11/03/custom-model-binding-using-imodelbinder-in-asp-net-mvc-two-gotchas/
garik - https://stackoverflow.com/a/2468447/578208
दिमित्री - https://stackoverflow.com/a/11903896/578208