Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC 2 - Html.EditorFor a nullable type?

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" )%>
like image 301
JK. Avatar asked Jul 24 '10 03:07

JK.


People also ask

What are display and editor templates in ASP NET MVC?

ASP.NET MVC has a feature called display and editor templates that let you specify in a central location how a given data type should be displayed.

What is editor htmlhelper in MVC?

HtmlHelper - Editor. We have seen different HtmlHelper methods used to generated different html elements in the previous sections. ASP.NET MVC also includes a method that generates html input elements based on the datatype. Editor() or EditorFor() extension method generates html elements based on the data type of the model object's property.

How to generate HTML elements from datatype in ASP NET MVC?

ASP.NET MVC includes the method that generates HTML input elements based on the datatype. The Html.Editor () or Html.EditorFor () extension methods generate HTML elements based on the data type of the model object's property. The following table list the data types and releted HTML elements:

How do I create an HTML control in MVC?

Create HTML Controls for Model Class Properties using EditorFor () ASP.NET MVC includes the method that generates HTML input elements based on the datatype. The Html.Editor () or Html.EditorFor () extension methods generate HTML elements based on the data type of the model object's property.


1 Answers

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" })%>
<% } %>
like image 135
JK. Avatar answered Oct 15 '22 11:10

JK.