ASP.NET MVC 2 – Html.Editor对于可以为空的类型?

我有两个编辑器模板:一个用于十进制,一个用于十进制? (可为空的)

但是当我的模型中有一个可以为空的小数时,它会尝试加载普通的十进制编辑器:

 model.SomeDecimal )%>  model.SomeNullableDecimal )%> 

第一个工作正常,并加载十进制编辑器模板。 第二个也尝试加载十进制模板(并且因为它不是十进制字段而失败)。

错误消息是:

 The model item passed into the dictionary is null, but this dictionary requires a non-null model item of type 'System.Decimal'. 

我的模板声明如下:

十进制模板:

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

可空的十进制模板:

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

我知道我可以通过传递模板名称来使其工作,例如

但我真的更喜欢它只是像所有其他模板一样使用类型自动工作。

  model.SomeNullableDecimal, "NullableDecimalTemplate" )%> 

感谢Bryan为了尝试获得积极的解决方案而增加赏金,但我将不得不回答并说我发现答案绝对没有 – 你不能从其类型中自动发现可以为空的模板。 您必须使用模板名称。

这是Brad Wilson博客http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-3-default-templates.html的相关引用。 他是MVC的权威来源,因此我必须相信他,当他说:

搜索类型名称时,使用简单名称(即Type.Name)而不使用名称空间。 此外,如果类型为Nullable,我们搜索T(因此,无论您使用的是“bool”还是“Nullable”,您都将获得布尔模板)

他还接着说

这意味着如果您正在为值类型编写模板,则需要考虑该值是否可为空。 您可以使用ModelMetadata的IsNullableValueType属性来确定该值是否可为空。 我们将在下面看到内置布尔模板的示例。

所以肯定有这个问题的答案,但不幸的是答案是否定的。

要使用可为空的模板,您必须明确使用模板名称:

 <%: Html.EditorFor(model => model.SomeNullableDecimal, "NullableDecimalTemplate" )%> 

或者您可以使用一个处理可空和非可空类型的模板:

 <% if (ViewData.ModelMetadata.IsNullableValueType) { %> <%= Html.DropDownList("", TriStateValues, new { @class = "list-box tri-state" })%> <% } else { %> <%= Html.CheckBox("", Value ?? false, new { @class = "check-box" })%> <% } %> 

要为可为空的类型创建模板,请将模板命名为基值类型,然后使用可为空的模型创建编辑器模板。

例如,我想为int做一个模板? 我创建了一个名为“int32.cshtml”的编辑器模板,我正在使用int? 作为模型。

如果您想了解更多详情,请访问: http : //www.campusmvp.net/blog/asp-net-mvc-editorfor-for-nullable-propierties

模板必须命名为“Nullable`1”。 由于这将匹配任何Nullable结构,因此您可以对模型类型进行切换,并根据“Nullable .1.ascx”中的类型呈现相应的部分模板。

没有办法以你想要的方式去做。 十进制和十进制只能有一个模板? 但是您可以在模板中确定传入的值是否为可空类型,如下所示:

 <% if (ViewData.ModelMetadata.IsNullableValueType) { %> <%= Html.DropDownList("", TriStateValues, new { @class = "list-box tri-state" })%> <% } else { %> <%= Html.CheckBox("", Value ?? false, new { @class = "check-box" })%> <% } %> 

有关详细信息,请查看此博文

是的,您可以在不指定Html.EditorFor中的模板的情况下执行此操作,但是您需要使用UIhint属性针对nullable属性指定模板。

 [UIHint("NullableDecimalTemplate")] public decimal? SomeNullableDecimal { get; set; }