C# 在自定义EditorFor中使用可为空的DateTime
我试图为我的ASP.NET MVC5页面创建一个自定义编辑器,但是当下面示例中的属性C# 在自定义EditorFor中使用可为空的DateTime,c#,asp.net,asp.net-mvc,datetime,C#,Asp.net,Asp.net Mvc,Datetime,我试图为我的ASP.NET MVC5页面创建一个自定义编辑器,但是当下面示例中的属性TProp为Nullable时,我收到一个错误。故障似乎发生在helper.EditorFor(属性)上。以下是错误: 传递到字典中的模型项为null,但此字典 需要类型为“System.DateTime”的非空模型项 代码如下: public static IHtmlString CustomEditorFor<TModel, TProp>(this HtmlHelper<TModel>
TProp
为Nullable
时,我收到一个错误。故障似乎发生在helper.EditorFor(属性)
上。以下是错误:
传递到字典中的模型项为null,但此字典
需要类型为“System.DateTime”的非空模型项
代码如下:
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);
}
引发错误的原因是您为
DateTime
创建了一个自定义EditorTemplate
,它由您的helper.EditorFor(属性)
在扩展方法中调用。这会将可为null的模型传递给一个视图,该视图需要日期时间
(不可为null)的模型
您可以通过将模板中的声明更改为
@model DateTime? // nullable
但是,对简单值类型同时使用调用EditorTemplate
的扩展方法没有什么意义,您应该使用其中一种方法
使用扩展方法,您的代码将是(注意,这使用了推荐的TagBuilder
类来生成html)
public static IHtmlString CustomEditorFor(此HtmlHelper帮助程序,表达式属性)
{
var name=ExpressionHelper.GetExpressionText(属性);
var metadata=modelmetada.FromLambdaExpression(属性,helper.ViewData);
var formatString=metadata.DisplayFormatString;
var watermark=metadata.watermark;
StringBuilder html=新的StringBuilder();
Append(helper.TextBoxFor(property,formatString,new{@class=“form control”,placeholder=watermark}));
Append(helper.ValidationMessageFor(property));
标记生成器容器=新标记生成器(“div”);
容器。添加CSSClass(“col-md-10”);
container.InnerHtml=html.ToString();
html=新的StringBuilder();
Append(helper.LabelFor(property));
Append(container.ToString());
容器=新标记生成器(“div”);
container.AddCssClass(“表单组”);
container.InnerHtml=html.ToString();
返回MvcHtmlString.Create(container.ToString());
}
该消息不是由扩展方法生成的,它的生成是因为您的视图具有@model DateTime
并且您将null
传递给它。(建议您使用TagBuilder
生成
元素)@StephenMuecke我添加了更多代码来显示我的视图和视图模型。我不太确定我是否明白你所说的。viewmodel不包含可为空的datetime属性。你能看看你以前的评论吗?你还没有提供相关信息。您显示的代码工作正常,扩展方法本身无法生成该错误。我猜您也有一个EditorTemplate
forDateTime
,它是由您的helper.EditorFor(property)
代码行呈现的。首先将helper.EditorFor(属性)
更改为helper.TextBoxForFor(属性)
。如果视图呈现正确,则显示您的日期时间
@StephenMuecke可能具有的任何编辑器或模板
。我尝试将EditorFor
更改为TextBoxFor
,它呈现了一个空文本框;没有错误。我已经为DateTime
添加了编辑器模板代码。即使我的viewmodel的属性是可为null的
,这是否会影响一些事情?是的,因为它的@model DateTime
(以及您传递它的DateTime?
)。它必须是@model DateTime?
。但是您在这里的实现实际上毫无意义(您可以使用扩展方法或EditorTemplate
,而不是两者都使用)。我将在30分钟左右添加一个更详细的答案(并展示如何使用TagBuilder
类)。注意:答案更新可以纠正水印问题(使用了错误的元数据)。是的,更新后的答案非常有效!谢谢你的帮助!
public Nullable<DateTime> DateUpgraded { get; set; }
@model DateTime
@Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue,
new { @class = "form-control", placeholder = ViewData.ModelMetadata.Watermark })
@model DateTime? // nullable
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());
}