ASP.NET MVC 2 - Html.Editor для обнуляемого типа?

У меня есть два шаблона редактора: один для десятичной, а другой для десятичной? (Обнуляемый)

Но когда у меня в модели есть пропускаемый десятичный знак, он пытается загрузить обычный десятичный редактор:

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

5 ответов

Решение

Спасибо Брайану за добавление награды за попытку получить положительное решение, но мне придется ответить и сказать, что я обнаружил, что ответ определенно НЕТ - вы не можете иметь автоматически обнаруживаемый шаблон с его типом. Вы должны использовать имя шаблона.

Это соответствующая цитата из блога Брэда Уилсона по адресу http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-3-default-templates.html. Он является авторитетным источником на MVC, поэтому я должен верить ему, когда он говорит:

При поиске имени типа используется простое имя (т. Е. Type.Name) без пространства имен. Кроме того, если тип Nullable, мы ищем T (так что вы получите логический шаблон, используете ли вы "bool" или "Nullable")

Он также продолжает говорить

Это означает, что если вы пишете шаблоны для типов значений, вам необходимо учитывать, является ли значение обнуляемым или нет. Вы можете использовать свойство Is NullableValueType для 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" })%>
<% } %>

Чтобы создать шаблон для типа, допускающего значение NULL, вы называете шаблон в качестве типа базового значения, а затем создаете шаблон редактора с моделью NULL.

Например, я хочу сделать шаблон для int? Я создал шаблон редактора с именем "int32.cshtml", и я использую int? как модель.

Если вы хотите получить дополнительную информацию, посмотрите здесь: http://www.campusmvp.net/blog/asp-net-mvc-editorfor-for-nullable-propierties

Шаблон должен быть назван "Nullable`1". Так как это будет соответствовать любой структуре Nullable, вы можете переключиться на тип модели и отобразить соответствующий частичный шаблон на основе типа из Nullable`1.ascx.

Да, вы можете сделать это без указания шаблона в Html.EditorFor, но тогда вам нужно указать шаблон для свойства nullable, используя атрибут UIhint.

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

Там нет никакого способа сделать это так, как вы хотите. Там может быть только один шаблон для десятичного и десятичного? Но вы можете определить в шаблоне, имеет ли передаваемое значение обнуляемый тип, например:

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

Для более подробной информации проверьте этот блог

Другие вопросы по тегам