Modell Bindung mit verschachtelten Kind Modelle und PartialViews in ASP.NET MVC
-
20-09-2019 - |
Frage
Ich habe folgende Typen und Klassen:
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 mag die Page
Instanz in meiner Edit.aspx
Ansicht bearbeiten. Da EditableContent
auch auf andere Modelle angebracht ist, habe ich eine PartialView
genannt ContentEditor.ascx
, die stark typisiert ist und nimmt eine Instanz von EditableContent
und macht es.
Der Rendering-Teil alles funktioniert gut, aber wenn ich poste - alles in meinem ContentEditor
nicht binded -. Das bedeutet, dass Page.Content
null
ist
Auf der PartialView, verwende ich stark typisierte Html-Helfer, 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 erhalten -. Die Werte sind nicht auf Page
binded
Ich habe versucht, lose typisierten 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 manuell Sammlung Indizes machen.
setzen sollte ich beide Seite und EditableContent als Parameter an die Controller-Aktion:
public ActionResult Edit(Page page, EditableContent content) { ... }
Was bin ich?
Lösung
Ich würde Ihnen vorschlagen, die EditorFor
Helfer verwenden
Modell:
public class EditableContent
{
public string SidebarLeft { get; set; }
public string SidebarRight { get; set; }
}
public class Page
{
public EditableContent Content { get; set; }
}
Ansichten / 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) %>
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);
}
}