asp.net-mvc 在 asp.net mvc 4 中格式化日期时间

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11272851/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 02:04:20  来源:igfitidea点击:

Format datetime in asp.net mvc 4

asp.net-mvcasp.net-mvc-4datetime-format

提问by amb

How can I force the format of datetime in asp.net mvc 4 ? In display mode it shows as I want but in edit model it doesn't. I am using displayfor and editorfor and applyformatineditmode=true with dataformatstring="{0:dd/MM/yyyy}" What I have tried:

如何在 asp.net mvc 4 中强制使用日期时间格式?在显示模式下,它按我的意愿显示,但在编辑模型中却没有。我正在使用 displayfor 和 editorfor 和 applyformatineditmode=true with dataformatstring="{0:dd/MM/yyyy}" 我尝试过的:

  • globalization in web.config (both of them) with my culture and uiculture.
  • modifying the culture and uiculture in application_start()
  • custom modelbinder for datetime
  • web.config(两者)中的全球化与我的文化和 uiculture。
  • 修改 application_start() 中的文化和用户文化
  • 日期时间的自定义模型绑定器

I have no idea how to force it and I need to input the date as dd/MM/yyyy not the default.

我不知道如何强制它,我需要输入日期为 dd/MM/yyyy 而不是默认值。

MORE INFO: my viewmodel is like this

更多信息:我的视图模型是这样的

    [DisplayName("date of birth")]
    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
    public DateTime? Birth { get; set; }

in view I use @Html.DisplayFor(m=>m.Birth)but this works as expected (I see the formatting) and to input the date I use @Html.EditorFor(m=>m.Birth)but if I try and input something like 13/12/2000 is fails with the error that it is not a valid date (12/13/2000 and 2000/12/13 are working as expected but I need dd/MM/yyyy).

鉴于我使用,@Html.DisplayFor(m=>m.Birth)但这按预期工作(我看到格式)并输入我使用的日期,@Html.EditorFor(m=>m.Birth)但如果我尝试输入 13/12/2000 之类的内容失败,并显示它不是有效日期的错误(12/ 13/2000 和 2000/12/13 按预期工作,但我需要 dd/MM/yyyy)。

The custom modelbinder is called in application_start() b/c I don't know where else.

自定义模型绑定器在 application_start() b/c 中调用,我不知道其他地方。

Using <globalization/>I have tried with culture="ro-RO", uiCulture="ro"and other cultures that would give me dd/MM/yyyy. I have also tried to set it on a per thread basis in application_start() (there are a lot of examples here, on how to do this)

使用<globalization/>我尝试过的culture="ro-RO", uiCulture="ro"其他文化会给我 dd/MM/yyyy。我还尝试在 application_start() 中基于每个线程设置它(这里有很多示例,关于如何执行此操作)



For all that will read this question: It seems that Darin Dimitrov's answer will work as long as I don't have client validation. Another approach is to use custom validation including client side validation. I'm glad I found this out before recreating the entire application.

对于所有将阅读这个问题的人:只要我没有客户验证,Darin Dimitrov 的答案似乎就会起作用。另一种方法是使用自定义验证,包括客户端验证。我很高兴在重新创建整个应用程序之前发现了这一点。

回答by Darin Dimitrov

Ahhhh, now it is clear. You seem to have problems binding back the value. Not with displaying it on the view. Indeed, that's the fault of the default model binder. You could write and use a custom one that will take into consideration the [DisplayFormat]attribute on your model. I have illustrated such a custom model binder here: https://stackoverflow.com/a/7836093/29407

啊哈,现在清楚了。您似乎在绑定值时遇到问题。不是在视图上显示它。事实上,这是默认模型绑定器的错误。您可以编写和使用一个自定义的,它会考虑[DisplayFormat]模型上的属性。我在这里说明了这样一个自定义模型绑定器:https: //stackoverflow.com/a/7836093/29407



Apparently some problems still persist. Here's my full setup working perfectly fine on both ASP.NET MVC 3 & 4 RC.

显然,一些问题仍然存在。这是我在 ASP.NET MVC 3 和 4 RC 上运行良好的完整设置。

Model:

模型:

public class MyViewModel
{
    [DisplayName("date of birth")]
    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
    public DateTime? Birth { get; set; }
}

Controller:

控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new MyViewModel
        {
            Birth = DateTime.Now
        });
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        return View(model);
    }
}

View:

看法:

@model MyViewModel

@using (Html.BeginForm())
{
    @Html.LabelFor(x => x.Birth)
    @Html.EditorFor(x => x.Birth)
    @Html.ValidationMessageFor(x => x.Birth)
    <button type="submit">OK</button>
}

Registration of the custom model binder in Application_Start:

在以下位置注册自定义模型绑定器Application_Start

ModelBinders.Binders.Add(typeof(DateTime?), new MyDateTimeModelBinder());

And the custom model binder itself:

和自定义模型绑定器本身:

public class MyDateTimeModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var displayFormat = bindingContext.ModelMetadata.DisplayFormatString;
        var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

        if (!string.IsNullOrEmpty(displayFormat) && value != null)
        {
            DateTime date;
            displayFormat = displayFormat.Replace("{0:", string.Empty).Replace("}", string.Empty);
            // use the format specified in the DisplayFormat attribute to parse the date
            if (DateTime.TryParseExact(value.AttemptedValue, displayFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
            {
                return date;
            }
            else
            {
                bindingContext.ModelState.AddModelError(
                    bindingContext.ModelName,
                    string.Format("{0} is an invalid date format", value.AttemptedValue)
                );
            }
        }

        return base.BindModel(controllerContext, bindingContext);
    }
}

Now, no matter what culture you have setup in your web.config (<globalization>element) or the current thread culture, the custom model binder will use the DisplayFormatattribute's date format when parsing nullable dates.

现在,无论您在 web.config ( <globalization>element) 中设置什么文化或当前线程文化,自定义模型绑定器DisplayFormat在解析可为空日期时都将使用属性的日期格式。

回答by lukyer

Client validation issues can occur because of MVC bug (even in MVC 5) in jquery.validate.unobtrusive.min.jswhich does not accept date/datetime format in any way. Unfortunately you have to solve it manually.

客户端验证问题可能是由于jquery.validate.unobtrusive.min.js 中的 MVC 错误(即使在 MVC 5 中)而发生它不以任何方式接受日期/日期时间格式。不幸的是,您必须手动解决它。

My finally working solution:

我的最终工作解决方案:

$(function () {
    $.validator.methods.date = function (value, element) {
        return this.optional(element) || moment(value, "DD.MM.YYYY", true).isValid();
    }
});

You have to include before:

您必须先包括:

@Scripts.Render("~/Scripts/jquery-3.1.1.js")
@Scripts.Render("~/Scripts/jquery.validate.min.js")
@Scripts.Render("~/Scripts/jquery.validate.unobtrusive.min.js")
@Scripts.Render("~/Scripts/moment.js")

You can install moment.js using:

您可以使用以下方法安装 moment.js:

Install-Package Moment.js

回答by Bashar Abu Shamaa

Thanks Darin, For me, to be able to post to the create method, It only worked after I modified the BindModel code to :

谢谢 Darin,对我来说,为了能够发布到 create 方法,它仅在我将 BindModel 代码修改为:

public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
    var displayFormat = bindingContext.ModelMetadata.DisplayFormatString;
    var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

    if (!string.IsNullOrEmpty(displayFormat) && value != null)
    {
        DateTime date;
        displayFormat = displayFormat.Replace("{0:", string.Empty).Replace("}", string.Empty);
        // use the format specified in the DisplayFormat attribute to parse the date
         if (DateTime.TryParse(value.AttemptedValue, CultureInfo.GetCultureInfo("en-GB"), DateTimeStyles.None, out date))
        {
            return date;
        }
        else
        {
            bindingContext.ModelState.AddModelError(
                bindingContext.ModelName,
                string.Format("{0} is an invalid date format", value.AttemptedValue)
            );
        }
    }

    return base.BindModel(controllerContext, bindingContext);
}

Hope this could help someone else...

希望这可以帮助别人......