【问题标题】:ASP.NET MVC 2 - Html.EditorFor a nullable type?ASP.NET MVC 2 - Html.EditorFor 可空类型?
【发布时间】:2011-03-20 10:05:02
【问题描述】:

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

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

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

【问题讨论】:

  • 您的模板名称是 Decimal.ascx 和 Decimal?.ascx 吗?
  • 不,它们是 Decimal.ascx 和 NullableDecimal.ascx
  • 没有人?.. 原来我可以通过在 Decimal.ascx 中复制 NullableDecimal.ascx 代码来“修复”它。奇怪的是,可以在可空模板中使用标准小数。我不知道为什么不可为空的小数会在具有以下代码的模板中工作: if (myDecimal.HasValue)
  • TimeSpan 也有同样的问题——我会用你的“修复”——非常感谢。
  • 几乎就像 Decimal 扩展了 Decimal?但我们知道它不是为什么 NullableDecimal 代码适用于 Decimal 模板?没有办法为可空类型提供特殊模板?

标签: c# asp.net-mvc asp.net-mvc-2 mvc-editor-templates editortemplates


【解决方案1】:

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

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

更多详情请查看this blog post

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 我的英国键盘布局失败了:P
    【解决方案3】:

    感谢 Bryan 添加赏金以尝试获得积极的解决方案,但我将不得不回答并说我发现答案绝对是否定的 - 您不能从自动发现可空模板它的类型。您必须使用模板名称。

    这是来自 Brad Wilson 博客http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-3-default-templates.html 的相关引述。他是 MVC 的权威人士,所以当他说:

    在搜索类型名称时, 使用简单名称(即 Type.Name) 没有命名空间。此外,如果类型 是可空的,我们搜索 T(所以 你会得到布尔模板 无论您使用的是“布尔”还是 “可以为空”)

    他还继续说

    这意味着如果您正在编写模板 对于值类型,您需要 说明值是否为 是否可以为空。您可以使用 IsNullableValueType 属性 ModelMetadata 来确定是否 值可以为空。我们会看到一个 下面的例子与 内置布尔模板。

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

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

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

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-06-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多