Почему ValidationMessageFor не отображает мое сообщение проверки в этом случае? - PullRequest
2 голосов
/ 13 апреля 2011

У меня есть модель представления, которая содержит 5 экземпляров класса в качестве под-свойств.Эти подчиненные свойства отображаются с использованием частичного представления следующим образом:

<%Html.RenderPartial("_EntryItemForm", Model.EntryItem1, new ViewDataDictionary { TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = "EntryItem1" } }); %>        
<%Html.RenderPartial("_EntryItemForm", Model.EntryItem2, new ViewDataDictionary { TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = "EntryItem2" } }); %>
<%Html.RenderPartial("_EntryItemForm", Model.EntryItem3, new ViewDataDictionary { TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = "EntryItem3" } }); %>
<%Html.RenderPartial("_EntryItemForm", Model.EntryItem4, new ViewDataDictionary { TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = "EntryItem4" } }); %>
<%Html.RenderPartial("_EntryItemForm", Model.EntryItem5, new ViewDataDictionary { TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = "EntryItem5" } }); %>

В частичном представлении у меня есть следующее (показывает только одно поле):

<%: Html.LabelFor<EntryItemForm, string>(x => x.ItemName)%>
<%: Html.TextBoxFor<EntryItemForm, string>(x => x.ItemName)%>
<%: Html.ValidationMessageFor(x => x.ItemName)%>

Меткаи текстовые поля отображаются с правильными идентификаторами, именами и т. д., и механизм связывания модели по умолчанию все прекрасно обрабатывает.

К сожалению, даже когда ModelState содержит ошибку для поля ItemName, ValidationMessage никогда не появляется.Если я добавлю ValidationSummary в родительское представление, отобразится ошибка.Обычно я просто использую ValidationSummary и продолжаю, но дизайн, над которым я работаю, требует встроенных проверочных сообщений.

Кто-нибудь знает, почему это может быть?

Ответы [ 3 ]

9 голосов
/ 18 мая 2011

Для тех, кто ищет эту проблему:

Проблема, вызванная тем, что ModelState не переходит к частичному представлению правильно, когда используется HtmlFieldPrefix.Этот html-помощник решил проблему (для меня), и ошибки проверки отображаются корректно:

public static void RenderPartialWithPrefix(this HtmlHelper helper, string partialViewName, object model, string prefix)
    {
        ViewDataDictionary WDD = new ViewDataDictionary {TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = prefix } };

        foreach(string key in helper.ViewData.ModelState.Keys)
        {
            if(key.StartsWith(prefix+"."))
            {
                foreach (ModelError err in helper.ViewData.ModelState[key].Errors)
                {
                  if(!string.IsNullOrEmpty(err.ErrorMessage))
                    WDD.ModelState.AddModelError(key, err.ErrorMessage);
                  if (err.Exception != null)
                      WDD.ModelState.AddModelError(key, err.Exception);
                }
                WDD.ModelState.SetModelValue(key, helper.ViewData.ModelState[key].Value);
            }
        }

        helper.RenderPartial(partialViewName,model,WDD);
    }

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

@{Html.RenderPartialWithPrefix("_StructureEditSharePartView", Model.sharePart,"sharePart");}
3 голосов
/ 13 апреля 2011

Возможно, имя поля, содержащего ошибку проверки в метаданных, не совпадает с именем поля, созданного помощником TextBoxFor. Как насчет использования шаблонов редактора? Таким образом, вам не нужно беспокоиться о префиксах, настройке информации о шаблонах, проблемах с проверкой, ...

Чтобы вы могли определить (~/Views/Shared/EditorTemplates/TypeOfEntryItem.ascx):

<%@ Control 
    Language="C#" 
    Inherits="System.Web.Mvc.ViewUserControl<AppName.Models.TypeOfEntryItem>"
%>
<%= Html.LabelFor(x => x.ItemName) %>
<%= Html.TextBoxFor(x => x.ItemName) %>
<%= Html.ValidationMessageFor(x => x.ItemName) %>

и в основном виде просто:

<% using (Html.BeginForm()) { %>
    <%= Html.EditorFor(x => x.EntryItem1) %>
    <%= Html.EditorFor(x => x.EntryItem2) %>
    <%= Html.EditorFor(x => x.EntryItem3) %>
    <%= Html.EditorFor(x => x.EntryItem4) %>
    <%= Html.EditorFor(x => x.EntryItem5) %>

    <input type="submit" value="OK" />
<% } %>

Это работает даже с коллекциями, если вы не хотите создавать 5 свойств в вашей модели. Вы можете иметь простое свойство:

public IEnumerable<TypeOfEntryItem> EntryItems { get; set; }

, а затем:

<% using (Html.BeginForm()) { %>
    <%= Html.EditorFor(x => x.EntryItems) %>
    <input type="submit" value="OK" />
<% } %>

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

2 голосов
/ 14 апреля 2011

http://www.dalsoft.co.uk/blog/index.php/2010/04/26/mvc-2-templates/#Complex_Types

Что касается вашего последнего вопроса о IEnumerable, ознакомьтесь со статьей выше для достойного обходного пути.Кроме того, я хотел бы, чтобы кто-нибудь ответил на ваш вопрос о том, как заставить вещи работать с htmlFieldPrefix ... «элегантным» или нет, нет смысла поддерживать отображение / рендеринг / обработку представления, если вы не можете поддерживать сообщения проверки.Я пытаюсь заставить EditorFor работать и для меня (сейчас), но если я когда-нибудь найду время и вернусь к тому, чтобы заставить его работать с RenderPartial, я вернусь сюда и опубликую решение.

ДляДля тех, кто может найти свой путь здесь путем поиска в Google, причина в том, что ModelState содержит ключи типа «ComplexObjectProperty.ModelProperty», но ValidationMessageFor пытается найти только «ModelProperty».Главный надзор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...