ASP.NET MVC 2 - Html.EditorFor для типа с нулевым значением?
У меня есть два шаблона редактора: один для десятичного и один для десятичного? (Обнуляемый)
Но когда у меня есть нулевое десятичное число в моей модели, он пытается загрузить нормальный десятичный редактор:
<%: 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>" %>
Nullable Decimal template:
<%@ Control Language="C#"
Inherits="System.Web.Mvc.ViewUserControl<System.Decimal?>" %>
Я знаю, что могу заставить его работать, передав имя шаблона, например
Но я бы предпочел, чтобы он просто работал автоматически, используя тип так же, как и все другие шаблоны.
<%: Html.EditorFor(model => model.SomeNullableDecimal,
"NullableDecimalTemplate" )%>
Ответы
Ответ 1
Спасибо Брайану за добавление щедрости, чтобы попытаться получить положительное решение, но мне нужно будет ответить и сказать, что я нашел, что ответ определенно НЕТ - вы не можете иметь автоопределяемый шаблон, его тип. Вы должны использовать имя шаблона.
Это соответствующая цитата из блога Брэда Уилсона на http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-3-default-templates.html. Он авторитетный источник на MVC, поэтому я должен ему поверить, когда он говорит:
При поиске имени типа используется простое имя (т.е. Type.Name) без пространства имен. Кроме того, если тип является Nullable, мы ищем T (so вы получите шаблон Boolean используете ли вы "bool" или "Nullable" )
Он также продолжает:
Это означает, что если вы пишете шаблоны для типов значений вам нужно будет учитывайте, является ли это значение nullable или нет. Вы можете использовать Свойство IsNullableValueType ModelMetadata, чтобы определить, значение равно NULL. Хорошо видеть пример этого ниже с встроенный булевский шаблон.
Итак, да, есть ответ на этот вопрос, но, к сожалению, ответ НЕТ.
Чтобы использовать шаблон с нулевым значением, вы должны явно использовать имя шаблона:
<%: Html.EditorFor(model => model.SomeNullableDecimal, "NullableDecimalTemplate" )%>
Или вы можете использовать один шаблон, который обрабатывает тип nullable и non-nullable:
<% if (ViewData.ModelMetadata.IsNullableValueType) { %>
<%= Html.DropDownList("", TriStateValues, new { @class = "list-box tri-state" })%>
<% } else { %>
<%= Html.CheckBox("", Value ?? false, new { @class = "check-box" })%>
<% } %>
Ответ 2
Чтобы создать шаблон для типа, допускающего значение NULL, вы называете шаблон в качестве типа базового значения, а затем создаете шаблон редактора с моделью NULL.
Например, я хочу сделать шаблон для int? Я создал шаблон редактора с именем "int32.cshtml", и я использую int? как модель.
Ответ 3
Шаблон должен быть назван "Nullable`1". Поскольку это будет соответствовать любой Nullable struct, вы можете сделать переключатель типа модели и отобразить соответствующий частичный шаблон на основе типа из "Nullable`1.ascx"
Ответ 4
Нет способа сделать это так, как вы хотите. Может быть только один шаблон для Decimal и Decimal?. Но вы можете определить в шаблоне, если переданное значение имеет тип NULL, например:
<% if (ViewData.ModelMetadata.IsNullableValueType) { %>
<%= Html.DropDownList("", TriStateValues, new { @class = "list-box tri-state" })%>
<% } else { %>
<%= Html.CheckBox("", Value ?? false, new { @class = "check-box" })%>
<% } %>
Подробнее... этот пост в блоге
Ответ 5
Да, вы можете сделать это без указания шаблона в Html.EditorFor, но тогда вам нужно указать шаблон для свойства nullable, используя атрибут UIhint.
[UIHint("NullableDecimalTemplate")]
public decimal? SomeNullableDecimal { get; set; }