2011-04-13 42 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

相关问题