简体   繁体   English

在自定义EditorFor中使用可空的DateTime

[英]Working with Nullable DateTime in Custom EditorFor

I am trying to create a custom editor for my ASP.NET MVC5 pages, but when the property TProp in the example below is a Nullable<DateTime> I receive an error. 我正在尝试为ASP.NET MVC5页面创建自定义编辑器,但是当下面示例中的TProp属性为Nullable<DateTime>我会收到错误消息。 The failure seems to happen on helper.EditorFor(Property) . 失败似乎发生在helper.EditorFor(Property) Here is the error: 这是错误:

The model item passed into the dictionary is null, but this dictionary requires a non-null model item of type 'System.DateTime'. 传递到字典中的模型项为null,但是此字典需要类型为'System.DateTime'的非空模型项。

Here is the code: 这是代码:

public static IHtmlString CustomEditorFor<TModel, TProp>(this HtmlHelper<TModel> helper,
    Expression<Func<TModel, TProp>> property)
{
    var htmlString =
        "<div class=\"form-group\">" +
            helper.LabelFor(property) +
            "<div class=\"col-md-10\">" +
                helper.EditorFor(property) +
                helper.ValidationMessageFor(property) +
            "</div>" +
        "</div>"
        ;
    return new HtmlString(htmlString);
}

EDIT: Adding Code reference code for for view, viewmodel and editor template 编辑:为视图,viewmodel和编辑器模板添加代码参考代码

View : Code that is attempting to render the viewmodel's values View :试图呈现视图模型值的代码

@model MyApp.Web.ViewModels.ProductViewModel

<div class="panel panel-primary">
    <div class="panel-heading">Upgrade Details</div>
    <div class="panel-body">
        <div class="form-horizontal">
            @Html.CustomEditorFor(model => model.DateUpgraded)
        </div>
    </div>
</div>

Viewmodel : this is the Nullable<DateTime> property that is not rendering Viewmodel :这是未渲染的Nullable<DateTime>属性

public Nullable<DateTime> DateUpgraded { get; set; }

EditorTemplate : editor template for DateTime EditorTemplateDateTime编辑器模板

@model DateTime
@Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue,
        new { @class = "form-control", placeholder = ViewData.ModelMetadata.Watermark })

The error is thrown because you created a custom EditorTemplate for DateTime which is called by your helper.EditorFor(property) in your extension method. 引发该错误是因为您为DateTime创建了一个自定义EditorTemplate ,该扩展helper.EditorFor(property)由扩展方法中的helper.EditorFor(property)调用。 This passes a model of Nullable<DateTime> to a view which expects a model which is DateTime (not nullable). 这会将Nullable<DateTime>模型传递给期望使用DateTime模型(不可为空)的视图。

You can solve the issue by changing the declaration in the template to 您可以通过将模板中的声明更改为

@model DateTime? // nullable

However, using both an extension method which calls an EditorTemplate for a simple value type makes little sense and you should be using one or the other. 但是,使用两种扩展方法EditorTemplate以为简单的值类型调用EditorTemplate方法几乎没有任何意义,因此您应该使用其中一种方法。

Using the extension method, your code would be (note this uses the recommended TagBuilder class for generating html) 使用扩展方法,您的代码将是(请注意,此代码使用推荐的TagBuilder类生成html)

public static IHtmlString CustomEditorFor<TModel, TProp>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProp>> property)
{
    var name = ExpressionHelper.GetExpressionText(property);
    var metadata = ModelMetadata.FromLambdaExpression(property, helper.ViewData);
    var formatString = metadata.DisplayFormatString;
    var watermark = metadata.Watermark;

    StringBuilder html = new StringBuilder();
    html.Append(helper.TextBoxFor(property, formatString, new { @class = "form-control", placeholder = watermark }));
    html.Append(helper.ValidationMessageFor(property));
    TagBuilder container = new TagBuilder("div");
    container.AddCssClass("col-md-10");
    container.InnerHtml = html.ToString();
    html = new StringBuilder();
    html.Append(helper.LabelFor(property));
    html.Append(container.ToString());
    container = new TagBuilder("div");
    container.AddCssClass("form-group");
    container.InnerHtml = html.ToString();
    return MvcHtmlString.Create(container.ToString());   
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM