我在使用某个DateTime Model属性的“远程”验证属性时遇到了以下不需要的行为.
服务器端,我的应用程序文化定义如下:
protected void Application_PreRequestHandlerExecute() { if (!(Context.Handler is IRequiresSessionState)){ return; } Thread.CurrentThread.CurrentCulture = new CultureInfo("nl-BE"); Thread.CurrentThread.CurrentUICulture = new CultureInfo("nl-BE"); }
客户端,我的应用文化定义如下:
Globalize.culture("nl-BE");
情况1:
>模型属性
[Remote("IsDateValid","Home")] public DateTime? MyDate { get; set; }
>控制器动作
public JsonResult IsDateValid(DateTime? MyDate) { // some validation code here return Json(true,JsonRequestBehavior.AllowGet); }
>在调试IsDateValid方法时,在UI中输入的日期为05/10/2013(2013年10月5日)被错误地解释为10/05/2013(2013年5月10日)
案例2:
>模型属性
[Remote("IsDateValid","Home",HttpMethod = "POST")] public DateTime? MyDate { get; set; }
>控制器动作
[HttpPost] public JsonResult IsDateValid(DateTime? MyDate) { // some validation code here return Json(true); }
>在调试IsDateValid方法时,在UI中输入的日期为05/10/2013(2013年10月5日)被正确解释为05/10/2013(2013年10月5日)
我是否缺少一些配置,以便根据需要进行“标准”GET远程验证?
解决方法
当绑定GET的数据时,使用
InvariantCulture
(这是“en-US”),而对于POST Thread.CurrentThread.CurrentCulture则是.背后的原因是GET URL可能由用户共享,因此应该是不变的.虽然从不共享POST,但使用服务器文化进行绑定是安全的.
如果您确定您的应用程序不需要在来自不同国家/地区的人之间共享URL,则可以安全地创建自己的ModelBinder
,即使对于GET请求也会强制使用服务器区域设置.
以下是Global.asax.cs中的示例:
protected void Application_Start() { /*some code*/ ModelBinders.Binders.Add(typeof(DateTime),new DateTimeModelBinder()); ModelBinders.Binders.Add(typeof(DateTime?),new DateTimeModelBinder()); } /// <summary> /// Allows to pass date using get using current server's culture instead of invariant culture. /// </summary> public class DateTimeModelBinder : IModelBinder { public object BindModel(ControllerContext controllerContext,ModelBindingContext bindingContext) { var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); var date = valueProviderResult.AttemptedValue; if (String.IsNullOrEmpty(date)) { return null; } bindingContext.ModelState.SetModelValue(bindingContext.ModelName,valueProviderResult); try { // Parse DateTimeusing current culture. return DateTime.Parse(date); } catch (Exception) { bindingContext.ModelState.AddModelError(bindingContext.ModelName,String.Format("\"{0}\" is invalid.",bindingContext.ModelName)); return null; } } }