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

 2023-02-17    384  

问题描述

ASP.NET-MVC现在允许对DateTime对象进行隐式绑定.我按照

的行动

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

public ActionResult DoSomething(DateTime startDate) 
{ 
... 
}

这将从AJAX调用成功转换为DateTime.但是,我们使用日期格式dd/mm/yyyy; MVC正在转换为mm/dd/yyyy.
例如,通过字符串’09/02/2009’提交呼叫的电话会导致’02/09/2009 00:00:00’或9月2日在我们的本地设置中.

.

我不想为了日期格式而滚动自己的模型活页夹.但是似乎不必更改操作以接受字符串然后使用dateTime.parse如果MVC是否能够为我执行此操作.

是否有任何方法可以更改日期时间的默认模型活页夹中使用的日期格式?默认模型活页夹是否应该使用您的本地化设置?

推荐答案

我刚刚通过一些更详尽的谷歌搜索找到了答案:

Melvyn Harbour对MVC为何与之合作的方式以及在必要时如何覆盖它的方式有详尽的解释:

:

寻找解析的值时,该框架以特定顺序查看:

  1. Routedata(未显示)
  2. uri查询字符串
  3. 请求表格

只有其中的最后一个才能意识到文化.从本地化的角度来看,有一个很好的理由.想象一下,我写了一个网络应用程序,显示了我在线发布的航空公司航班信息.我通过单击当天的链接来查找特定日期的航班(也许像 httpp ://www.melsflighttimes.com/flights/2008-11-21 ),然后想通过电子邮件将其链接到我的同事.我们可以保证我们俩都会查看同一数据页面的唯一方法是使用不变性文化.相比之下,如果我使用表格预订我的航班,那么一切都会在一个紧张的周期中发生.当数据写入表单时,数据可以尊重当前文化,因此在从表单中返回时需要尊重它.

其他推荐答案

我将在全球范围内树立您的文化. Modelbinder接管了!

<system.web>
    <globalization uiCulture="en-AU" culture="en-AU" />

否则您只需更改此页面.
但是在web中全球.我认为更好

其他推荐答案

我遇到了与DateTime模型属性绑定的短期格式的相同问题.在查看了许多不同的示例(不仅与DateTime有关)之后,我将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;
            }
        }
    }
}

要保留全局ASAX文件中的路由等方式,我还向我的MVC4项目的APP_START文件夹添加了一个新的sytatic类.

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拨打静态寄存器custmostelbinders:

protected void Application_Start()
{
    /* bla blah bla the usual stuff and then */

    CustomModelBindersConfig.RegisterCustomModelBinders();
}

这里的一个重要说明是,如果您将DateTime值写入这样的隐藏字段:

@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: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中,则它将无法工作,因为它将其分配给了会话的当前线程.如您所知,Web应用程序无状态,因此先前为您的请求提供服务的线程与您当前请求的服务相同,因此您的文化信息已转到数字天空中的Great GC.

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

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

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

以上所述是小编给大家介绍的MVC的DateTime绑定有不正确的日期格式,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!

原文链接:https://77isp.com/post/34226.html

=========================================

https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。