将Datetime Model值绑定到datepicker并将它们传递给controller方法

时间:2013-11-21 16:20:13

标签: html jquery-ui asp.net-mvc-4 date datepicker

我正在构建一个MVC4应用程序,在我的模型中我有这些字段:

[DisplayFormat(DataFormatString = "{0:dd-MM-yyyy}", ApplyFormatInEditMode = true)]
public DateTime mDateCreated { get; set; }

[DisplayFormat(DataFormatString = "{0:dd-MM-yyyy}", ApplyFormatInEditMode = true)]
public DateTime? mDateModified { get; set; }

[DisplayFormat(DataFormatString = "{0:dd-MM-yyyy}", ApplyFormatInEditMode = true)]
public DateTime? mDateLastDisplayed { get; set; }

[DisplayFormat(DataFormatString = "{0:dd-MM-yyyy}", ApplyFormatInEditMode = true)]
public DateTime mStartDate { get; set; }

[DisplayFormat(DataFormatString = "{0:dd-MM-yyyy}", ApplyFormatInEditMode = true)]
public DateTime? mEndDate { get; set; }

我正在尝试在视图中设置日期选择器。以下是我到目前为止所做的事情:

<div class="float-left">
    <p>Date Created:</p>
    <p>Date of last modification:</p>
    <p>Date Last Displayed:</p>
    <p>Date of promotion's start:</p>
    <p>Date of promotion's end:</p>
</div>
<div class="float-right">
    <p>
        @Html.TextBoxFor(_item => _item.mCardOfTheDay.mDateCreated, new
            {
                @value = Model.mCardOfTheDay.mDateCreated,
                @selectedDate = Model.mCardOfTheDay.mDateCreated,
                @class = "datePick",
                @type = "date",
                @id = "dateCreated"
            })
    </p>
    <p>
        @(Model.mCardOfTheDay.mDateModified != null ? Html.DisplayFor(_item => _item.mCardOfTheDay.mDateModified) : Html.Label(ValueDomain.FIELD_UNAVAILABLE))
    </p>
    <p>@(Model.mCardOfTheDay.mDateLastDisplayed != null ? Html.DisplayFor(_item => _item.mCardOfTheDay.mDateLastDisplayed) : Html.Label(ValueDomain.FIELD_UNAVAILABLE))</p>
    <p>
        @*@Html.EditorFor(_item => _item.mCardOfTheDay.mStartDate, new { @class = "datePick", @type="date" })*@
        @*@Html.TextBoxFor(_item => _item.mCardOfTheDay.mStartDate, new {@id = "dateStart"})*@
      @*  @Html.TextBoxFor(_item => _item.mCardOfTheDay.mStartDate, new
            {
                @value = (DateTime?) Model.mCardOfTheDay.mStartDate,
                @selectedDate = (DateTime?) Model.mCardOfTheDay.mStartDate,
                @class = "datePick",
                @type = "date",
                @id = "dateStart"
            })*@
    </p>
    <p>
        @Html.TextBoxFor(_item => _item.mCardOfTheDay.mEndDate, new
            {
                @value = Model.mCardOfTheDay.mEndDate,
                @selectedDate = Model.mCardOfTheDay.mEndDate,
                @class = "datePick",
                @type = "date",
                @id = "dateEnd"
            })
    </p>
</div>
<div class="clear"></div>

用CSS来展示我在做什么:

$('.datePick').datepicker({
    dateFormat: "dd/ww/yy",
});

$('.datePick').each(function () {
    var a = $(this).datepicker({
        dateFormat: "dd/ww/yy",
        defaultDate: new Date($(this).val())
    });
});

这显示了我遇到的各种问题。第一:

  1. Html.TexborFor@value等处使用@selectedDate帮助程序会显示一个日期选择器,但此日期选择器的默认显示值为aaaa-mm-dd绑定到模型的值,当我将模型传递给控制器​​时,没有保留任何数据(意味着mEndDate始终为null);
  2. 仅尝试设置日期选择器最终会得到相同的结果;
  3. 这里有一个Html代码示例,向您展示我的“结果”:<input class="input-validation-error datePick" data-val="true" data-val-date="The field mDateCreated must be a date." data-val-required="The mDateCreated field is required." id="dateCreated" name="mCardOfTheDay.mDateCreated" selectedDate="11/21/2013 00:00:00" type="date" value="" />
  4. 如果我使用EditorFor,我所拥有的只是字符串格式的日期,没有日期选择器。
  5. 我想要的是一个日期选择器,其中选择了适当的日期,将所选日期传递给post中的控制器方法。任何人都可以帮我弄清楚为什么这不起作用?

2 个答案:

答案 0 :(得分:4)

您不应该以不同的格式覆盖具有相同日期的日期输入的值,没有理由而且它只会引起麻烦。根据我的经验,你最好离开它。

@Html.TextBoxFor(_item => _item.mCardOfTheDay.mDateCreated, new
{
    @selectedDate = Model.mCardOfTheDay.mDateCreated,
    @class = "datePick",
    @type = "date",
    @id = "dateCreated"
})

然而,您需要做的是正确配置datepicker,以便它知道如何解释来自数据库的日期。如果您希望向用户显示与发布回服务器的格式不同的格式,则可以使用altFieldsource)和altFormatsource ) 选项。

这将允许您使用dateFormat以您在用户输入中的任何格式显示日期,同时保持发布的值的格式正确。

你不再需要这个了:

$('.datePick').each(function () {
    var a = $(this).datepicker({
        dateFormat: "dd/ww/yy",
        defaultDate: new Date($(this).val())
    });
});

您还需要在模型属性属性上删除ApplyFormatInEditMode = true。让框架根据当前文化处理日期,不要试图通过在整个地方应用格式来对抗它。

只需将文本框值保留为数据库发送的任何值,并使用数据导航器的功能在客户端执行所需的操作。

我建议覆盖该值的唯一时间是,如果您担心输入显示时间部分,而您只需要日期。在这种情况下,你应该这样做:

@Html.TextBoxFor(_item => _item.mCardOfTheDay.mDateCreated, new
{
    @selectedDate = Model.mCardOfTheDay.mDateCreated,
    @class = "datePick",
    @type = "date",
    @id = "dateCreated",
    @Value = Model.mCardOfTheDay.mDateCreated.ToString("mm/d/yyyy")
})

注意@Value带有大写字母v,这实际上很重要而不是拼写错误。然后,您将日期格式传递给ToString方法,但它必须与数据库格式相同。


修改

我继续并构建了一个小测试用例来尝试复制您的问题。这就是我所拥有的:

控制器:

public ActionResult Test()
{
    return View(new TestViewModel()
    {
        DateCreated = DateTime.Now.AddDays(10)
    });
}

[HttpPost]
public ActionResult Test(TestViewModel model)
{
    return RedirectToAction("Test");
}

ViewModel:

public class TestViewModel
{
    public DateTime DateCreated { get; set; }
}

查看:

@using (Html.BeginForm())
{
    @Html.TextBoxFor(m => m.DateCreated, new {
        @type = "date",
        @Value = Model.DateCreated.ToString("d")
    })
    <input type="submit">
}

// This is the rendered input
<input Value="12/1/2013" data-val="true" data-val-date="The field DateCreated must be a date." id="DateCreated" name="DateCreated" type="date" value="12/1/2013 4:03:19 PM" />

JS:

$('input[type="date"]').datepicker();

这一切都按预期工作; datepicker默认选择输入值中的日期,model.DateCreated的值设置为帖子上的DateTime对象。请注意我没有在任何地方搞乱格式,而是在显示值中用标准短日期模式替换完整日期。

您是否可以尝试简化代码以匹配我所拥有的代码并让我知道会发生什么?

答案 1 :(得分:2)

好吧,经过这么多年你肯定已经解决了这个问题,但仍然想回答所有对这个问题不熟悉的人:

datepicker应采用YYYY-MM-DD格式作为其值。单个数字的天数和月份应填0,1月为01.您只需将日期格式修改为

即可
 @Value = Model.DateCreated.ToString("yyyy-MM-dd")