2010-03-17 8 views
9

Ich habe folgende Typen und Klassen:Modell Bindung mit verschachtelten Kind Modelle und PartialViews in ASP.NET MVC

namespace MVC.Models 

public class Page 
{ 
    public EditableContent Content {get; set; } 
} 

public class EditableContent 
{ 
    public TemplateSection SidebarLeft {get; set; } 
    public TemplateSection SidebarRight {get; set; } 
} 

ich die Page Instanz in meinem Edit.aspx Ansicht bearbeiten möchten. Da EditableContent auch an andere Modelle angeschlossen ist, habe ich eine PartialView namens ContentEditor.ascx, die stark typisiert ist und eine Instanz von EditableContent übernimmt und rendert.

Das Rendering Teil funktioniert alles gut, aber wenn ich poste - alles in meinem ContentEditor ist nicht gebunden - was bedeutet, dass Page.Content ist null.

Auf der PartialView, verwende ich getippt Html-Helfer stark, dies zu tun:

<%= Html.HiddenFor(m => m.TemplateId) %> 

Aber weil die Eingabeelemente auf dem Formular, das von ContentEditor.ascx gerendert wird nicht den Content Präfix seines id Attribut bekommen - die Werte sind nicht an Page gebunden.

Ich habe versucht, lose typisiert Helfer mit, dies zu überwinden:

<%= Html.Hidden("Content.TemplateId", Model.TemplateId) %> 

Und wenn ich mit einer Eigenschaft zu tun habe, die eine List<T> von etwas ist es sehr hässlich wird. Ich muss dann Sammlungsindizes manuell rendern.

Sollte lege ich beide Seite und EditableContent als Parameter an die Controller-Aktion ?:

public ActionResult Edit(Page page, EditableContent content) { ... } 

Was bin ich?

Antwort

18

Ich würde Ihnen vorschlagen, die EditorFor Helfer

Modell zu verwenden:

public class EditableContent 
{ 
    public string SidebarLeft { get; set; } 
    public string SidebarRight { get; set; } 
} 

public class Page 
{ 
    public EditableContent Content { get; set; } 
} 

Views/Home/Index.aspx:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<ToDD.Models.Page>" %> 

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> 
    Home Page 
</asp:Content> 

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> 
<% using (Html.BeginForm()) { %> 
    <%-- 
    This is the important part: It will look for 
    Views/Shared/EditorTemplates/EditableContent.ascx 
    and render it. You could also specify a prefix 
    --%> 
    <%= Html.EditorFor(page => page.Content, "Content") %> 
    <input type="submit" value="create" /> 
<% } %> 
</asp:Content> 

Ansichten/Shared/EditorTemplates/EditableContent.ascx :

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ToDD.Models.EditableContent>" %> 

<%= Html.TextBoxFor(m => m.SidebarLeft) %> 
<br/> 
<%= Html.TextBoxFor(m => m.SidebarRight) %> 

Und schließlich Controller/HomeController:

public class HomeController : Controller 
{ 
    public ActionResult Edit() 
    { 
     var page = new Page 
     { 
      Content = new EditableContent 
      { 
       SidebarLeft = "left", 
       SidebarRight = "right" 
      } 
     }; 
     return View(page); 
    } 

    [HttpPost] 
    public ActionResult Edit(Page page) 
    { 
     return View(page); 
    } 
} 
+1

Es funktioniert, Alter! Vielen Dank. Ich gehe davon aus, dass der EditorFor sich um das Gerüst kümmert, um alles zusammenzubinden. – MartinHN

+1

Ich habe dies auf einem Projekt von mir gemacht, aber können Sie erklären, warum 'Html.RenderPartial (" _ blah ", Model.Blah)' nicht funktioniert? So hatten wir das früher. – GONeale

+7

@GONeale, es funktioniert nicht, weil Sie Model.Blah übergeben, also innerhalb des Partiellen sind Sie im Kontext von Blah, nicht im Kontext von Model => alle Helfer, die Sie in diesem Teil verwenden, erzeugen falsche Eingabenamen. Editor-Templates sind anders => sie berücksichtigen den übergeordneten Kontext und generieren Helfer, die in ihnen verwendet werden, erzeugen korrekte Eingabenamen. Sehen Sie sich nur Ihr Markup an und Sie werden sofort den Unterschied sehen. Damit die Standardmodellmappe funktioniert, müssen Sie die Konventionen beachten. –