【问题标题】:Format Date On Binding (ASP.NET MVC)绑定日期格式 (ASP.NET MVC)
【发布时间】:2008-09-25 14:25:48
【问题描述】:

在我的 ASP.net MVC 应用程序中,我的视图如下所示:

...
<label>Due Date</label>
<%=Html.TextBox("due")%>
...

我正在使用ModelBinder 将帖子绑定到我的模型(到期属性为DateTime 类型)。问题是当我将“01/01/2009”放入文本框中时,帖子没有验证(由于其他数据输入不正确)。活页夹使用日期和时间“01/01/2009 00:00:00”重新填充它。

有没有办法告诉活页夹正确格式化日期(即ToShortDateString())?

【问题讨论】:

标签: asp.net-mvc


【解决方案1】:

我刚刚遇到了这个非常简单优雅的解决方案,在 MVC 2 中可用:

http://geekswithblogs.net/michelotti/archive/2010/02/05/mvc-2-editor-template-with-datetime.aspx

基本上,如果您使用的是 MVC 2.0,请在您的视图中使用以下内容。

 <%=Html.LabelFor(m => m.due) %>
 <%=Html.EditorFor(m => m.due)%>

然后在 /Views/Shared/EditorTemplates 中创建一个局部视图,名为 DateTime.ascx

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<System.DateTime?>" %>
<%=Html.TextBox("", (Model.HasValue ? Model.Value.ToShortDateString() : string.Empty), new { @class = "datePicker" }) %>

当 EditorFor 被调用时,它会找到一个匹配的编辑器模板。

【讨论】:

  • 这对我有用,但它肯定会替换 DateTimes 的 all 个实例...如果您对不同实例有不同的格式要求怎么办?
  • @saw-lau:您可以像上面那样创建多个不同名称的模板,然后根据需要将模板名称作为第二个参数传递给 Html.EditorFor()。
【解决方案2】:

DataType 属性装饰模型中的属性,并指定它是Date,而不是DateTime

public class Model {
  [DataType(DataType.Date)]
  public DateTime? Due { get; set; }
}

您也必须在视图中使用EditorFor 而不是TextBoxFor

@Html.EditorFor(m => m.Due)

【讨论】:

    【解决方案3】:

    这是一个肮脏的黑客,但它似乎工作。

    <%= Html.TextBoxFor(model => model.SomeDate,
        new Dictionary<string, object> { { "Value", Model.SomeDate.ToShortDateString() } })%>
    

    您获得模型绑定,并且能够使用格式化字符串覆盖文本字段的 HTML“值”属性。

    【讨论】:

    • 我喜欢。短而甜。这是我的细微变化: model.SomeDate, new { @Value = Model.SomeDate.ToShortDateString() } )%>
    • 为你们俩+1,这个小技巧为我节省了很多时间:)。
    • 在启用客户端验证的情况下不起作用,因为该日期将使用模型中的日期,并且如果它正在验证的区域设置的格式不同,它将阻止提交。
    【解决方案4】:

    我自己在寻找答案时发现了这个问题。上面的解决方案对我不起作用,因为我的 DateTime 可以为空。这是我通过支持可为空的 DateTime 对象来解决它的方法。

    <%= Html.TextBox(String.Format("{0:d}", Model.Property)) %>
    

    【讨论】:

    • 错了,@Quoo 的答案也适用于可为空的 DateTime。刚刚测试过了。
    • 看看日期,网络英雄。他的答案是在我的一年多之后发布的。
    【解决方案5】:

    你为什么不使用

    <% =Html.TextBox("due", Model.due.ToShortDateString()) %>
    

    【讨论】:

    • Corin 想要输入日期而不仅仅是显示日期。该问题与所需格式的绑定日期有关。
    【解决方案6】:

    首先,添加这个扩展来获取属性路径:

    public static class ExpressionParseHelper
    {
        public static string GetPropertyPath<TEntity, TProperty>(Expression<Func<TEntity, TProperty>> property)
        {                       
             Match match = Regex.Match(property.ToString(), @"^[^\.]+\.([^\(\)]+)$");
             return match.Groups[1].Value;
        }
    }
    

    比为 HtmlHelper 添加这个扩展:

     public static MvcHtmlString DateBoxFor<TEntity>(
                    this HtmlHelper helper,
                    TEntity model,
                    Expression<Func<TEntity, DateTime?>> property,
                    object htmlAttributes)
                {
                    DateTime? date = property.Compile().Invoke(model);
                    var value = date.HasValue ? date.Value.ToShortDateString() : string.Empty;
                    var name = ExpressionParseHelper.GetPropertyPath(property);
    
                    return helper.TextBox(name, value, htmlAttributes);
                }
    

    你还应该添加这个 jQuery 代码:

    $(function() {
        $("input.datebox").datepicker();
    });
    

    datepicker 是一个 jQuery 插件。

    现在你可以使用它了:

    <%= Html.DateBoxFor(Model, (x => x.Entity.SomeDate), new { @class = "datebox" }) %>
    

    ASP.NET MVC2 and DateTime Format

    【讨论】:

      【解决方案7】:

      为了在视图后面的代码中获得对模型的强类型访问,您可以这样做:

      public partial class SomethingView : ViewPage<T>
      {
      }
      

      其中 T 是您要从 Action 中传入的 ViewData 类型。

      然后在你的控制器中你会有一个动作:

      public ActionResult Something(){
          T myObject = new T();
          T.Property = DateTime.Today();
      
          Return View("Something", myObject);
      }
      

      之后,您的视图中有很好的强类型模型数据,因此您可以这样做:

      <label>My Property</label>
      <%=Html.TextBox(ViewData.Model.Property.ToShortDateString())%>
      

      【讨论】:

      • 感谢您的回复。我知道强类型页面及其带来的好处,我相信这更适用于编辑视图。我特别关注适用于使用模型绑定器的信息(在创建视图中)。
      【解决方案8】:

      我发现最好的方法是重置 ModelValue

      ModelState.SetModelValue("due", new ValueProviderResult(
             due.ToShortDateString(), 
             due.ToShortDateString(), 
             null));
      

      【讨论】:

        【解决方案9】:

        我想我个人认为最好或最简单的方法是通过强类型页面和一些定义的模型类来实现,但如果你希望它成为活页夹中的东西,我会这样做:

        public class SomeTypeBinder : IModelBinder
        {
            public object GetValue(ControllerContext controllerContext, string modelName,
                                      Type modelType, ModelStateDictionary modelState)
            {
                SomeType temp = new SomeType();
                //assign values normally
                //If an error then add formatted date to ViewState
                controllerContext.Controller.ViewData.Add("FormattedDate",
                                      temp.Date.ToShortDateString());
            }
        }
        

        然后在创建文本框时在视图中使用它,即:

        <%= Html.TextBox("FormattedDate") %>
        

        希望对您有所帮助。

        【讨论】:

          【解决方案10】:

          这对我有用:mvc 2

          &lt;%: Html.TextBoxFor(m =&gt; m.myDate, new { @value = Model.myDate.ToShortDateString()}) %&gt;

          简单又甜美!

          user82646 的评论,我想我会让它更显眼。

          【讨论】:

            【解决方案11】:

            试试这个

            <%:Html.TextBoxFor(m => m.FromDate, new { @Value = (String.Format("{0:dd/MM/yyyy}", Model.FromDate)) }) %>
            

            【讨论】:

              【解决方案12】:

              MVC4 EF5 视图我试图用今天的日期预加载一个字段,然后将其传递给视图以供批准。

              ViewModel.SEnd = DateTime.Now    //preload todays date  
              return View(ViewModel)           //pass to view
              

              在视图中,我的第一个代码允许编辑:

              @Html.EditedFor(item.SEnd)        //allow edit
              

              后来我把它改成只显示日期,用户无法更改,但提交触发控制器保存更改

               <td>
               @Html.DisplyFor(item.SEnd)       //show no edit
               </td>
              

              当我更改为 DisplayFor 时,我需要添加它以确保将预加载的值传递回控制器。我还需要为视图模型中的每个字段添加 HiddenFor。

                  @Html.HiddenFor(model => model.SEnd)     //preserve value for passback.
              

              初学者的东西,但需要一段时间才能解决。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2010-10-18
                • 1970-01-01
                • 2013-10-11
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多