12

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

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

<%: Html.EditorFor(model => model.SomeDecimal )%>
<%: Html.EditorFor(model => 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<System.Decimal>" %>

可空十进制模板:

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

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

但我真的希望它像所有其他模板一样使用类型自动工作。

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

5 回答 5

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" )%>

或者,您可以使用一个模板来处理可空类型和不可空类型:

<% if (ViewData.ModelMetadata.IsNullableValueType) { %>
    <%= Html.DropDownList("", TriStateValues, new { @class = "list-box tri-state" })%>
<% } else { %>
    <%= Html.CheckBox("", Value ?? false, new { @class = "check-box" })%>
<% } %>
于 2011-03-15T10:22:09.080 回答
2

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

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

于 2014-07-29T20:12:12.070 回答
1

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

于 2011-03-10T18:52:07.503 回答
0

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

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

有关更多详细信息,请查看此博客文章

于 2011-02-14T18:49:31.080 回答
0

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

[UIHint("NullableDecimalTemplate")]
public decimal? SomeNullableDecimal { get; set; }
于 2017-01-11T06:09:33.500 回答