ASP.NET MVC 2 - Html.EditorFor 可空类型?

发布于 2024-09-11 08:55:49 字数 988 浏览 0 评论 0原文

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

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

<%: 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'. 

我的模板声明如下:

Decimal template:

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

Nullable Decimal template:

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

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

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

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

I have two editor templates: one for decimal, and one for decimal? (nullable)

But when I have a nullable decimal in my model, it tries to load the normal decimal editor:

<%: Html.EditorFor(model => model.SomeDecimal )%>
<%: Html.EditorFor(model => model.SomeNullableDecimal )%>

The first one works fine, and loads the decimal editor template. The second one also tries to load the decimal template (and fails because it is not a decimal field).

The error message is:

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

My templates are declared like this:

Decimal template:

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

Nullable Decimal template:

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

I know that I can make it work by passing in the template name, eg

But I would really prefer it to just work automatically by using the type just like all the other templates.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

千年*琉璃梦 2024-09-18 08:55:53

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

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

有关更多详细信息,请检查 这篇博文

There is no way to do it in the way you want. There can be only one template for Decimal and Decimal?. But you can determine in the template if the value passed in is of nullable type like this:

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

For more details check this blog post

萧瑟寒风 2024-09-18 08:55:53

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

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

Yes, you can do this without specifying the template in Html.EditorFor, but then you need specify the template against nullable property using the UIhint attribute.

[UIHint("NullableDecimalTemplate")]
public decimal? SomeNullableDecimal { get; set; }
烟火散人牵绊 2024-09-18 08:55:52

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

The template would have to be named "Nullable`1". Since this would match any Nullable struct, you could do a switch on the model type and render the appropriate partial template based on the type from within the "Nullable`1.ascx"

近箐 2024-09-18 08:55:51

感谢 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”还是
“可为空”)

他还接着说

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

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

要使用可为 null 的模板,您必须显式使用模板名称:

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

或者您可以使用一个同时处理可为 null 和不可为 null 类型的模板:

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

Thanks to Bryan for adding a bounty to try to get a positive solution, but I'm going to have to answer and say that I have found that the answer is definitely NO - you cannot have a nullable template auto-discovered from its type. You must use a template name.

This is the relevant quote from Brad Wilson's blog at http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-3-default-templates.html. He is an authoritative source on MVC so I have to believe him when he says:

When searching for the type name, the
simple name is used (i.e., Type.Name)
without namespace. Also, if the type
is Nullable, we search for T (so
you’ll get the Boolean template
whether you’re using “bool” or
“Nullable”)

He also goes on to say

This means if you’re writing templates
for value types, you will need to
account for whether the value is
nullable or not. You can use the
IsNullableValueType property of
ModelMetadata to determine if the
value is nullable. We’ll see an
example of this below with the
built-in Boolean template.

So YES there is an answer to this question, but unfortunately the answer is NO.

To use a nullable template you must explictly use the template name:

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

Or you can use one template that handle both the nullable and the non nullable type:

<% if (ViewData.ModelMetadata.IsNullableValueType) { %>
    <%= Html.DropDownList("", TriStateValues, new { @class = "list-box tri-state" })%>
<% } else { %>
    <%= Html.CheckBox("", Value ?? false, new { @class = "check-box" })%>
<% } %>
幸福还没到 2024-09-18 08:55:51

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

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

In order to create a template for a nullable type, you name your template as the base value type and then create your editor template with a nullable model.

For example, I want to do a template for int?. I created an editor template named "int32.cshtml" and I'm using int? as the model.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文