如何使用3个字段为DateTime创建编辑器模板?

Bru*_*oLM 7 c# asp.net-mvc editortemplates asp.net-mvc-3

我想创建一个编辑器模板DateTime,我需要3个独立的字段:

(DropDown) Day    |    (DropDown) Month    |    (DropDown) Year
Run Code Online (Sandbox Code Playgroud)

我如何以及在何处创建此文件?DateTime当我发布到控制器时,我需要做什么才能将这3个字段变为单个字段?

Jam*_*ack 3

在您的Views/Shared/EditorTemplates文件夹中创建一个名为 的局部视图DateTime.ascx

此 EditorTemplate 的代码应该类似于

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<DateTime?>" %>

<%
    string controlId = ViewData.TemplateInfo.HtmlFieldPrefix.Replace('.', '_');
%>

<script type="text/javascript">
$(function () {
    $('#<%: controlId %>_Day, #<%: controlId %>_Month, #<%: controlId %>_Year').live('change', function () { updateHiddenDate('<%: controlId %>'); });
    $('#<%: controlId %>_Day').val('<%: Model.HasValue ? Model.Value.Day.ToString() : "" %>');
    $('#<%: controlId %>_Month').val('<%: Model.HasValue ? Model.Value.Month.ToString() : "" %>');
    $('#<%: controlId %>_Year').val('<%: Model.HasValue ? Model.Value.Year.ToString() : "" %>');
    updateHiddenDate('<%: controlId %>');
});

function updateHiddenDate(hiddenDateId) {
    $('#' + hiddenDateId).val($('#' + hiddenDateId + '_Year').val() + "-" + $('#' + hiddenDateId + '_Month').val() + "-" + $('#' + hiddenDateId + '_Day').val());
}
</script>

<select id="<%: controlId %>_Day">
<%  for (int dayOrdinal = 1; dayOrdinal <= 31; dayOrdinal++)
    {
        Response.Write(string.Format("<option value=\"{0}\">{0}</option>", dayOrdinal));
    }
%>
</select>
<select id="<%: controlId %>_Month">
<%  for (int monthOrdinal = 1; monthOrdinal <= 12; monthOrdinal++)
    {
        Response.Write(string.Format("<option value=\"{0}\">{1}</option>", monthOrdinal, System.Globalization.DateTimeFormatInfo.CurrentInfo.MonthNames[monthOrdinal - 1]));
    }
%>
</select>
<select id="<%: controlId %>_Year">
<%  for (int yearOrdinal = DateTime.Now.Year - 5; yearOrdinal <= DateTime.Now.Year + 5; yearOrdinal++)
    {
        Response.Write(string.Format("<option value=\"{0}\">{0}</option>", yearOrdinal));
    }
%>
</select>

<%: Html.Hidden("", Model.HasValue ? String.Format("{0:yyyy-MM-dd}", Model) : "") %>
Run Code Online (Sandbox Code Playgroud)

这将创建一个带有隐藏字段的编辑器模板,其中包含 MVC ModelBinder 可以解析的 ISO 8601 日期表示形式。

每当下拉菜单发生变化时,jQuery 都会更新隐藏字段。ViewData.TemplateInfo.HtmlFieldPrefix请注意我用来生成id隐藏字段的的使用。

请注意,此解决方案很容易使用,而不会与自定义 ModelBinder 发生冲突,因为我们构造了一个包含完整日期时间的单个表单值。然而,这确实意味着

  1. 您依赖启用了 JavaScript 的客户端,并且
  2. 您需要在母版页中包含对 jQuery 库的脚本引用(例如<script type="text/javascript" src="../../Scripts/jquery-1.4.1.min.js"></script>

如果这是不可接受的,您将不得不像 @Jon 指出的那样查看自定义 ModelBinders。