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

JK.*_*JK. 12 c# asp.net-mvc mvc-editor-templates editortemplates asp.net-mvc-2

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

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

<%: Html.EditorFor(model => model.SomeDecimal )%>
<%: Html.EditorFor(model => model.SomeNullableDecimal )%>
Run Code Online (Sandbox Code Playgroud)

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

错误消息是:

The model item passed into the dictionary is null, but this dictionary requires 
a non-null model item of type 'System.Decimal'. 
Run Code Online (Sandbox Code Playgroud)

我的模板声明如下:

十进制模板:

<%@ Control Language="C#" 
Inherits="System.Web.Mvc.ViewUserControl<System.Decimal>" %>
Run Code Online (Sandbox Code Playgroud)

可空的十进制模板:

<%@ Control Language="C#" 
Inherits="System.Web.Mvc.ViewUserControl<System.Decimal?>" %>
Run Code Online (Sandbox Code Playgroud)

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

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

<%: Html.EditorFor(model => model.SomeNullableDecimal, 
"NullableDecimalTemplate" )%>
Run Code Online (Sandbox Code Playgroud)

JK.*_*JK. 16

感谢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" )%>
Run Code Online (Sandbox Code Playgroud)

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

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