首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >MVC DateTime绑定的日期格式不正确

MVC DateTime绑定的日期格式不正确
EN

Stack Overflow用户
提问于 2009-02-09 15:14:05
回答 8查看 154.9K关注 0票数 137

now MVC现在允许DateTime对象的隐式绑定。我有一个类似于

代码语言:javascript
复制
public ActionResult DoSomething(DateTime startDate) 
{ 
... 
}

这成功地将字符串从ajax调用转换为DateTime。但是,我们使用日期格式dd/MM/yyyy;MVC转换为MM/dd/yyyy。例如,提交包含字符串'09/02/2009‘的操作调用将导致DateTime为'02/09/2009 00:00:00',或者在我们的本地设置中为9月2日。

我不想为了日期格式而滚动我自己的模型活页夹。但是,如果MVC能够为我做这件事,那么似乎没有必要将操作更改为接受字符串,然后使用DateTime.Parse。

有没有办法改变DateTime默认模型绑定器中使用的日期格式?默认的模型绑定器不应该使用您的本地化设置吗?

EN

回答 8

Stack Overflow用户

发布于 2010-05-24 20:37:43

我会在全球范围内设置你的文化。ModelBinder把它捡起来!

代码语言:javascript
复制
  <system.web>
    <globalization uiCulture="en-AU" culture="en-AU" />

或者您只需为此页面更改此设置。

但从全局来看,在web.config中我认为更好

票数 38
EN

Stack Overflow用户

发布于 2013-07-15 18:00:14

我在将短日期格式绑定到DateTime模型属性时也遇到了同样的问题。在看了许多不同的例子(不仅仅是关于DateTime)之后,我把下面的内容放在一起:

代码语言:javascript
复制
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;
            }
        }
    }
}

为了保持路由等在全局ASAX文件中的regiseterd方式,我还在我的MVC4项目的App_Start文件夹中添加了一个名为CustomModelBinderConfig的新sytatic类:

代码语言:javascript
复制
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());
        }
    }
}

然后我就像这样从我的Global ASASX Application_Start调用静态RegisterCustomModelBinders:

代码语言:javascript
复制
protected void Application_Start()
{
    /* bla blah bla the usual stuff and then */

    CustomModelBindersConfig.RegisterCustomModelBinders();
}

这里一个重要的注意事项是,如果您将一个DateTime值写入一个隐藏字段,如下所示:

代码语言:javascript
复制
@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中为每个请求设置区域性信息:

代码语言:javascript
复制
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中,它将不会工作,因为这会将它分配给会话的当前线程。如你所知,web应用程序是无状态的,所以之前服务你的请求的线程不是服务于你的当前请求的线程,因此你的文化信息已经到了数字天空中的伟大GC。

感谢访问: Ivan Zlatev - http://ivanz.com/2010/11/03/custom-model-binding-using-imodelbinder-in-asp-net-mvc-two-gotchas/

garik - https://stackoverflow.com/a/2468447/578208

Dmitry - https://stackoverflow.com/a/11903896/578208

票数 32
EN

Stack Overflow用户

发布于 2012-08-10 22:35:22

在MVC3中会略有不同。

假设我们有一个控制器和一个带有Get方法的视图

代码语言:javascript
复制
public ActionResult DoSomething(DateTime dateTime)
{
    return View();
}

我们应该添加ModelBinder

代码语言:javascript
复制
public class DateTimeBinder : IModelBinder
{
    #region IModelBinder Members
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        DateTime dateTime;
        if (DateTime.TryParse(controllerContext.HttpContext.Request.QueryString["dateTime"], CultureInfo.GetCultureInfo("en-GB"), DateTimeStyles.None, out dateTime))
            return dateTime;
        //else
        return new DateTime();//or another appropriate default ;
    }
    #endregion
}

以及Global.asax的Application_Start()中的命令

代码语言:javascript
复制
ModelBinders.Binders.Add(typeof(DateTime), new DateTimeBinder());
票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/528545

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档