10
votes

Modèle Reliure sur plusieurs modèles de formulaire Soumission de la vue fortement typée

J'ai des problèmes liés à une forme avec plusieurs modèles soumis. J'ai un formulaire de plainte qui inclut des informations sur les plaintes ainsi que des plaignants un à plusieurs. J'essaie de soumettre le formulaire mais je reçois des erreurs sur la liaison. Modelstate.isvalid retourne toujours faux.

Si je débobile et affiche les erreurs de modèles de modèle, j'entiens un dicton: "L'entréeCollection a déjà été initialisée. La méthode d'initialisateLateLatedCollection ne doit être appelée que pour initialiser une nouvelle entitéCollection lors de la désérialisation d'un graphique d'objet". P>

Aussi, lorsque le modèle de plainte obtient, je peux voir que le modèle de plainte reçoit peuplé de plaignants de la soumission de formulaire, il semble donc que la partie fonctionne. p>

Je ne sais pas si ce que je fais n'est pas possible avec le modèle de mod modèle par défaut, ou si je ne vais pas tout simplement pas aller à ce sujet la bonne façon. Je n'arrive pas à trouver des exemples concrets ni de la documentation à ce sujet. Un problème très similaire peut être trouvé sur Stackoverflow ici Mais cela ne semble pas traiter avec des points de vue fortement tapés. p>

Code du contrôleur: P>

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

<%= Html.ValidationSummary() %>
<% using (Html.BeginForm()) {%>

<table cellpadding="0" cellspacing="0" class="table">
    <tr>
        <td>
        <label for="DateReceived">Date Received:</label>
            <%= Html.TextBox("DateReceived") %>
            <%= Html.ValidationMessage("DateReceived", "*") %>    
        </td>
        <td>
            <label for="DateEntered">Date Entered:</label>
            <%= Html.TextBox("DateEntered")%>
            <%= Html.ValidationMessage("DateEntered", "*") %>
        </td>
    </tr>
    <tr>
        <td>
            <label for="Concluded">Concluded:</label>
            <%= Html.CheckBox("Concluded")%>
            <%= Html.ValidationMessage("Concluded", "*") %>
            </td>
        <td>
            <label for="IncidentDate">Incident Date:</label>
            <%= Html.TextBox("IncidentDate")%>
            <%= Html.ValidationMessage("IncidentDate", "*") %></td>
    </tr>
</table>
    <hr />
    <table>
    <% if (Model != null) {
           int i = 0;
       foreach (var complainant in Model.Complainants){ %>
       <%= Html.Hidden("Complainants[" + i + "].Id", complainant.Id)%>
    <tr>
        <td>
            <label for="Surname">Surname:</label>

            <%= Html.TextBox("Complainants[" + i + "].Surname", complainant.Surname)%>
            <%= Html.ValidationMessage("Surname", "*")%>
        </td>
        <td>
            <label for="GivenName1">GivenName1:</label>
            <%= Html.TextBox("Complainants[" + i + "].GivenName1", complainant.GivenName1)%>
            <%= Html.ValidationMessage("GivenName1", "*")%>
        </td>
    </tr>
    <% i++; %>
    <% }} %>
    <tr>
        <td colspan=2>
            <input type="submit" value="Submit" />
        </td>
    </tr>
</table>
<% } %>
<div>
    <%=Html.ActionLink("Back to List", "Index") %>
</div>


0 commentaires

5 Réponses :


3
votes

Aveu d'aveugle:

Modification: xxx

avec: xxx

respectivement - ajouter "plainte". Avant «Les plaignants [...»

Modifier :

Ce n'est pas une bonne réponse. Laissé il est indigne simplement parce que cela pourrait ajouter une certaine valeur jusqu'à ce que la réponse appropriée apparaisse.

EDIT2:

Je pourrais vous tromper, mais pour moi, il semble qu'il y ait Problème avec le cadre d'entité (ou - avec la façon dont vous l'utilisez). Je veux dire - ASP.NET MVC parvient à lire des valeurs de la demande mais ne peut pas initialiser la collection de plaignants.

ici Il est écrit:

La méthode InitializerELatedCollection (TTAREGENTITY) Initialise une encollection (tente) existante créée à l'aide du constructeur par défaut. L'entitéCollection (tente) est initialisée en utilisant la relation fournie et les noms de rôle cibles.

La méthode InitializerLatedCollection (TTArgetentialité) est utilisée pendant la désérialisation uniquement.

Quelques informations supplémentaires:

Exception:

  • InvalidOperationException

    Conditions:

    • Lorsque l'entité fourni (tente) est déjà initialisée.
    • Lorsque le gestionnaire de relations est déjà attaché à un objetContext.
    • Lorsque le gestionnaire de relations contient déjà une relation avec ce nom et ce rôle cible.

      Un whiteImateImateLateLatedCollection est tiré deux fois. Malheureusement - je n'ai aucune idée brillante pourquoi exactement. Peut-être que cette petite enquête aidera à quelqu'un d'autre - plus expérimenté avec EF. :)

      Edit3:

      Ce n'est pas une solution pour ce problème particulier, plus comme une solution de contournement, un moyen approprié de gérer une partie du modèle de MVC.

      créer une vue de vue à des fins de présentation uniquement. Créez un nouveau modèle de domaine à partir de PURE POCOS (car EF les prendra les plus en prendre en charge dans la version suivante). Utilisez automapper pour mapper efdataContext <=> Modèle <=> ViewModel.

      Ce serait Prenez des efforts, mais c'est comme ça que cela devrait être traité. Cette approche supprime la prestation de la responsabilité de votre modèle, nettoie votre modèle de domaine (supprime les choses EF de votre modèle) et résoudrait votre problème avec la liaison.


5 commentaires

J'ai essayé ceci mais modelstate.isvalid retourne toujours faux. Les touches de modélisation sont peuplées avec des complications [0] noms de deuil, plaignants [1] noms, etc. La chose qui la cause échoue est une clé appelée plaignante. C'est ce qui me donne l'erreur "L'entitéCollection a déjà été initialisée. La méthode InitializeriateLatedCollection ne doit être appelée que pour initialiser une nouvelle entitéCollection lors de la désérialisation d'un graphique d'objet".


Cela peut être un problème lors de l'utilisation d'entitésCollections. Ce lien: Distribucon.com/aspnetmvcrc1bindingalist.aspx Brefly parle de ça mais je Je ne sais pas assez de tout cela pour décider s'il s'agit ou non de la raison pour laquelle cela ne fonctionne pas.


J'ai le même problème. Les éléments de la collection sont liés, mais le modèle de modèle a l'erreur. La collection liée a l'air bien, mais c'est des relations est null. Cela peut être un indice ou un hareng rouge.


@Arnis L., oui j'utilise ef. En raison de la complexité et de ma résistance aux solutions de contournement, je vais aller un itinéraire différent. Merci pour ton aide


Ouais, très non impressionné avec EF jusqu'à présent. Les choses qui sont faciles avec NHibernate et d'autres ormes semblent être une montagne escarpée de EF. Cela dit, j'ai presque toujours suivi votre "contournement" d'utiliser une vue de vue au lieu de l'entité de domaine actuelle de toute application de la signification de toute façon, il suffit de B / C l'architecture en couches signifie souvent que les objets ont des formes différentes de différentes couches.



0
votes

J'ai eu le problème identique! À la fin, vous découvrirez que le framework ne peut pas gérer des modèles complexes.

J'ai écrit un petit composant contraignant pouvant initialiser les fixations complexes sur un post.

Mais essentiellement ce que vous avez à faire est ce que Arnis L. dit.


0 commentaires

1
votes

J'ai travaillé autour de l'exception de modélisation en procédant comme suit: xxx

L'inconvénient principal est que l'exception est toujours lancée et qui peut être coûteuse au moment de l'exécution. L'élégant travail autour peut être de créer une enveloppe autour du boîtier par défaut existant et de l'empêcher d'instantifier l'entitéCollection à nouveau, qui est déjà effectuée par EF. Ensuite, contraignant cette collecte aux valeurs de formulaire (FormCollection).

Gardez à l'esprit si vous contraignez plus d'une collection, vous devrez supprimer l'erreur de chaque collection.

Dans mon expérience, la collection a sauvegardé avec succès ainsi que le objet root dans le graphique que la collection faisait partie de.

espère que cela aide quelqu'un d'autre.


1 commentaires

Est-ce la seule différence du code de @ Woopstash et votre collection de plaintes économisait-elle définitivement? Je ne pense pas que l'applicationPropertychanchants sauvegardera les propriétés de navigation ou les collections. Lorsque j'ai essayé, il suffit de sauve les valeurs de scaler et la documentation semble confirmer cela.



3
votes
public ActionResult Edit([Bind(Exclude = "Complainants")]Complaint model)
{
  TryUpdateModel(model.Complainants, "Complainants");
  if (!ModelState.IsValid)
  {
      // return the pre populated model
      return View(model);
  }

}
This works for me!I think that when Complaint object gets created then its 'Complainants' collection  gets initialized (because of entity framework auto logic) and then model binder tries to create the collection itself as well, which causes the error.
But when we try to update the model manually then collection is already initialized but model binder is not asked to initialize it again.

0 commentaires

2
votes

Pour que cela fonctionne sans solution de contournement au cas par cas, vous devez créer votre propre liant de modèle et la méthode de remplacement de la méthode SetProperty:

ModelBinders.Binders.DefaultBinder = new MyDefaultModelBinder();


1 commentaires

Pour tous ceux qui ont cette erreur avec l'entité Framework 4, utilisez ce que Jake E propose. Cela fonctionne bien. Merci Jake et merci à l'auteur posté cette erreur.