2011-04-13 38 views
2

我有一個視圖模型,它包含一個類的5個實例作爲子屬性。這些子屬性是使用一個局部視圖中呈現,如下所示:爲什麼ValidationMessageFor在這種情況下顯示我的驗證消息?

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

標籤和文本框都呈現使用正確的ID,名稱等,默認的模型綁定器可以完美地處理所有事情。

不幸的是,即使ModelState包含ItemName字段的錯誤,ValidationMessage也不會出現。如果我向父視圖添加ValidationSummary,則會顯示錯誤。通常我只是使用ValidationSummary並繼續前進,但我正在努力的設計需要內聯驗證消息。

有沒有人有任何想法,爲什麼這可能是?

回答

3

也許元數據中包含驗證錯誤的字段的名稱與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" /> 
<% } %> 

這會使集合中,當然,照顧生成正確編號,名稱的每個項目的編輯模板,.. 。

+0

謝謝你的建議。我試着用你指定的方式來使用EditorFor,而我完全沒有:沒有錯誤,也沒有輸出!任何想法可能會導致什麼? – 2011-04-13 09:07:36

+0

@Paul Suart,編輯器模板的名稱和位置很重要。它必須位於'〜/ Views/Shared/EditorTemplates'文件夾中,並命名爲'XXX.ascx',其中'XXX'是它強類型的名稱。這必須是「EntryItem1」屬性的類型。 – 2011-04-13 10:15:07

+0

嗯,我得到了EditorFor <>去(是我自己的錯,因爲我沒有意識到它輸出一個MvcHtmlString而不是寫入響應),但仍然沒有喜悅。已經更新了這個問題。 – 2011-04-13 20:58:19

2

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

關於你提到的有關IEnumerable的最後一個問題,看看上面一個體面的解決方法的文章。另外,我希望有人會回答你關於使用htmlFieldPrefix進行工作的問題......「優雅」或沒有,如果你不支持驗證消息,那麼支持視圖的顯示/渲染/處理就沒有意義了。我試圖讓EditorFor爲我工作(現在),但如果我得到時間並返回使其與RenderPartial一起工作,我會回到這裏併發布解決方案。

對於那些可能通過Googling問題找到方法的人,原因是ModelState包含諸如「ComplexObjectProperty.ModelProperty」之類的鍵,但ValidationMessageFor嘗試只查找「ModelProperty」。主要監督。

+0

所以我必須使用UIHint?看起來像小精靈給我!我也得出了ValidationMessageFor無法在ModelState中查找右鍵的結論。 – 2011-04-15 00:17:01

9

有人誰是谷歌搜索這個麻煩:

問題造成的原因的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");} 
+1

這是一個巨大的幫助,謝謝!最後,我還創建了一個名爲PartialWithPrefix的Partial版本,它在最後調用helper.Partial(而不是helper.RenderPartial),並返回MvcHtmlString。 – 2011-12-01 21:39:51

+0

我不得不添加另一個條件,其中我的partial是一個列表,並且在html中有[0]個索引。 如果(key.StartsWith(前綴+ 「[」)) 這裏是我在的ModelState Command.PSoftAccessRequirements.PSoftAccountsPayable.VoucherApprovalMatrix [0] .LEVELValidation 前綴= Command.PSoftAccessRequirements.PSoftAccountsPayable.VoucherApprovalMatrix – 2014-01-07 23:01:12

+0

鍵這是一個救生員,謝謝!這應該是一個被接受的答案。確保'前綴'的外殼與ModelState.Keys匹配。我使用ToLowerInvariant()來檢查密鑰是否以前綴開始。 – NetWave 2016-04-20 07:47:08

相關問題