2010-03-17 14 views
9

modelu mam następujące rodzaje i klasy:wiązania z zagnieżdżonych modeli dziecięcych i PartialViews w 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; } 
} 

Chcę zmienić instancję Page w moim Edit.aspx View. Ponieważ EditableContent jest również dołączony do innych modeli, mam PartialView o nazwie ContentEditor.ascx, który jest silnie wpisany i pobiera instancję EditableContent i renderuje ją.

Część renderowania działa dobrze, ale kiedy zamieszczam - wszystko wewnątrz mojego ContentEditor nie jest wiązane - co oznacza, że ​​Page.Content to .

Na PartialView używam silnie wpisany kod HTML pomocników, aby to zrobić:

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

Ale ponieważ elementy wejściowe w formularzu, które są świadczone przez ContentEditor.ascx nie dostać prefiks Content jego atrybutem id - w wartości nie są powiązane z Page.

Próbowałem za pomocą luźno wpisywanych pomocników do pokonania to:

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

A kiedy mam do czynienia z nieruchomości, która jest List<T> coś robi się bardzo brzydki. Następnie muszę ręcznie renderować indeksy kolekcji.

powinienem umieścić zarówno stronę i EditableContent jako parametry do działania kontrolera ?:

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

Czego mi brakuje?

Odpowiedz

18

Proponuję do korzystania z EditorFor pomocnik

Model:

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> 

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

I wreszcie Kontroler/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

Działa, koleś! Dzięki. Zakładam, że EditorFor dba o to, aby wszystkie rusztowania łączyły wszystko. – MartinHN

+1

Zrobiłem to na moim projekcie, ale czy możesz wyjaśnić, dlaczego 'Html.RenderPartial (" _ blah ", Model.Blah)' nie działa Darin? Tak jak to było wcześniej. – GONeale

+7

@GONeale, to nie działa, ponieważ przekazujesz Model.Blah, więc w częściowym jesteś w kontekście Blah, nie w kontekście Model => wszyscy pomocnicy, których używasz w tym częściowym generowaniu błędnych nazw wejściowych. Szablony edytorów są różne => biorą pod uwagę kontekst nadrzędny i generują pomocników, które są używane wewnątrz nich, generują odpowiednie nazwy wejściowe. Wystarczy spojrzeć na swoje oznaczenia, a od razu zauważysz różnicę. Aby domyślny spinacz modelu działał, musisz przestrzegać konwencji. –

Powiązane problemy