2010-08-17 8 views
0

J'ai un modèle que je peux lier correctement à des fins d'affichage, mais je ne peux pas poster une version mise à jour.ASP.Net MVC Model Binding

Je peux afficher une page et sa liste de contenu dans un formulaire de mise à jour dans une vue fortement typée. Mais lorsque je publie un modèle mis à jour, c'est-à-dire si j'ai modifié un contenu de type pagecontents, le modèle publié contient les détails de Pages mais perd la relation entre la page et le contenu de la page.

Ainsi, lorsque j'obtiens la page à des fins d'affichage, la page PageContenu étendue contient les bons résultats.

Mais lorsque je mets à jour et que Post PageContents ne contient aucune entrée de page.

(peut BTW être un hareng rouge, mais j'utilise Fluent NHibernate)

Malheureusement, je ne peux pas trouver ce que je suis absent.

Alors, voici une version abrégée de mon code:

public class Page 
{ 
    public virtual int Id { get; private set; } 
    public virtual string Name { get; set; } 
    public virtual string Title { get; set; } 

    public virtual IList<PageContent> PageContents { get; private set; } 

    public Page() 
    { 
     PageContents = new List<PageContent>(); 
    } 

    public virtual void AddPageContent(PageContent pageContent) 
    { 
     pageContent.Page = this; 
     PageContents.Add(pageContent); 
    } 
} 


public class PageContent 
{ 
    public virtual int Id { get; private set; } 
    public virtual string Name { get; set; } 
    public virtual string Description { get; set; } 
    public virtual string Content { get; set; } 
    public virtual Page Page { get; set; } 
} 
Page <%= Html.LabelFor(model => model.Title) %>: 
<%= Html.TextBoxFor(model => model.Title, new { @class = "wide-input" })%> 
<%= Html.ValidationMessageFor(model => model.Title) %> 

Page <%= Html.LabelFor(model => model.Name) %>: 
<%= Html.TextBoxFor(model => model.Name, new { @class = "wide-input" })%> 
<%= Html.ValidationMessageFor(model => model.Name) %> 

<% 
    foreach (var item in Model.PageContents) 
    { 
%> 
     <%= Html.TextAreaFor(m => item.Content) %> 

<% 
    } 
%> 

<p><input type="submit" value="Save" /></p> 

<% } %> 

Répondre

1

Fondamentalement, vous avez besoin ID uniques pour chaque élément de la liste. Quelque chose comme

<input id="PageContents_0_Content" name="PageContents[0].Content" value="..." /> 

Cela peut se faire par:

<%= Html.TextBox(string.Format("PageContents[{0}].Content", i), Model.Products[i].Id) %> 

Cette cette blogpost:

http://weblogs.asp.net/nmarun/archive/2010/03/13/asp-net-mvc-2-model-binding-for-a-collection.aspx

Cette blogpost décrit une bien meilleure solution:

http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/

Il utilise sa propre méthode HTML Helper pour initialiser les liaisons de liste.

EDIT: Je mal compris, se concentrait sur des collections avec ASP.NET MVC:

si je changeais un contenu pagecontents alors le modèle affiché contient les détails pages, mais perd la relation entre la page et le pagecontent. Pour autant que je sache MVC ne peut pas restaurer cette relation.

Si Page contient déjà PageContent après un PostBack alors tout est "bien". Moyens: Vos collections sont correctement postées. Mais MVC n'a aucune idée de votre page PageContent.Page. Donc, vous devez restaurer si manuellement.

EDIT2:

(peut BTW être un hareng rouge, mais j'utilise Fluent NHibernate)

Si j'interprète que correctement vous utilisez votre modèle directement pour lier votre point de vue - droite?Si c'est le cas, je suggère que vous créiez ViewModels, en copiant tout de votre modèle et retour. Cela découplerait le modèle de la vue. Votre ViewModel pourrait fournir beaucoup plus d'informations nécessaires à votre vue. Voir le modèle MVVM.

+0

Merci pour votre réponse - J'ai changé mon code pour le <% = Html.TextArea (string.Format ("PageContents [{0}]. Content", i), Model.PageContents [i] .Content)%> mais le problème reste le même. Lorsque le contrôleur reçoit la page de post contient une collection de PageContents qui, à toutes fins utiles, sont nouveaux et ne contiennent pas de référence à Page. –

+0

oui Je vais descendre la route ViewModel. Je pense que j'ai été pris dans un double-penser! –