2010-12-10 7 views
2

J'ai lu beaucoup de messages similaires sur le modèle null, mais mon cas est très très simple et toujours le modèle sur Créer une action est nul. Qu'est-ce que je fais mal???Le modèle est null?

Voici la situation: Une vue principale, deux vues partielles fortement typées à l'intérieur, chacune liée à une propriété publique du modèle principal. Toute aide est appréciée. modèles:

public class SimpleModel1 
{ 
    public IEnumerable<string> SomeStrings1 { get; set; } 
} 

public class SimpleModel2 
{ 
    public IEnumerable<string> SomeStrings2 { get; set; } 
} 

public class ComplexModel 
{ 
    public SimpleModel1 model1 { get; set; } 
    public SimpleModel2 model2 { get; set; } 
    public IEnumerable<string> SomeStringsComplex { get; set; } 
} 

int il contrôleur :

public ActionResult Create() 
    { 
     ComplexModel complex = new ComplexModel(); 
     complex.model1 = new SimpleModel1(); 
     complex.model1.SomeStrings1 = new List<string> { "a1", "a2", "a3"}; 

     complex.model2 = new SimpleModel2(); 
     complex.model2.SomeStrings2 = new List<string> { "b1", "b2", "b3" }; 

     complex.SomeStringsComplex = new List<string> { "c1", "c2", "c3" }; 
     return View(complex); 
    } 

    [HttpPost] 
    public ActionResult Create(ComplexModel model) 
    { 
     if (ModelState.IsValid) 
     { 
      var test = model.SomeStringsComplex; 
     } 
     return View(); 
    } 

Vues: 2 vues partielles fortes -Chaque pour le modèle

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

<fieldset> 
    <legend>Fields</legend> 
    <% foreach (string item in Model.SomeStrings2) 
      {%> 
      <p> 
      <label for="Title">Item Title:</label> 
      <%= Html.TextBox(item,item)%>    
      </p> 
      <% 
      } 
     %> 
</fieldset> 

1 vue principale:

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

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

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> 

<h2>Create</h2> 
<% using (Html.BeginForm()) {%> 
<fieldset> 
<div> Own values 
<% foreach (string item in Model.SomeStringsComplex) 
      {%> 
      <p> 
      <label for="Title">Item Title:</label> 
      <%= Html.TextBox(item,item) %>   
      </p> 
      <% 
      } 
     %> 
</div> 
<div>Simple values 1 
<%Html.RenderPartial("SimpleModelView1", this.ViewData.Model.model1, new ViewDataDictionary()); %> 
</div> 

<div>Simple values 2 
<%Html.RenderPartial("SimpleModelView2", Model.model2, new ViewDataDictionary()); %> 
</div> 
<p> 
      <input type="submit" value="Create" /> 
     </p> 
</fieldset> 
<% } %> 

+0

Voulez-vous dire que vous obtenez un '' NullReferenceException' au test var = model.SomeStringsComplex; '' parce que model' est nul? – SwDevMan81

+0

@ SwDevMan81: Je pense qu'il était, et je pense que cela se passait parce qu'il n'envoyait rien dans la vue: 'return View();', mais OP n'a jamais commenté cela. – ANeves

Répondre

2

Je vais prendre un coup de poignard sauvage et dire la validation de votre modèle échoue lors de la publication d'un ComplexModel au serveur

Votre validation du modèle n'a pas à l'échec du tout. Vous ne retournez pas quoi que ce soit à l'intérieur du bloc vous if donc toujours retourner un Voir sans modèle associé:

if (ModelState.IsValid) 
{ 
    var test = model.SomeStringsComplex; 
} 
return View(); // View is called with no Model data 

A en juger par votre code, qui causerait la vue Créer être instancié sans modèle. Cela peut être corrigé assez simplement:

[HttpPost] 
public ActionResult Create(ComplexModel model) 
{ 
    if (ModelState.IsValid) 
    { 
     var test = model.SomeStringsComplex; 
     // Do something to Create the object 

     RedirectToAction("Index"); 
    } 

    // Model State is invalid, return so the user can correct 
    return View(model); 
} 
+0

non - c'était la première fois que j'ai vérifié –

+0

la vue de création montre les données correctement mais quand elle est postée - le modèle est nul –

+0

+1 bon point à propos de ne rien retourner si 'ModelState.IsValid' est' true'. Cela ne devrait-il pas générer une erreur, "tous les chemins de code ne renvoient-ils pas une valeur"? –

1

N'êtes-vous pas censé envoyer quelque chose à la vue, sur cette ligne?

return View(); 
0

Je pense que le problème est de savoir comment vous indiquez vos champs de texte - le modèle de liaison ne sait pas comment les assigner de nouveau aux propriétés qu'ils viennent.

Vous pouvez lire cet article Haacked qui décrit comment utiliser modèle de liaison pour les propriétés énumérables:

http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx

+0

il y a un point dans cela - mais j'ai changé tous les accessoires IEnumerable dans tous les modèles avec int simple et la seule valeur qui n'est pas nulle dans l'action de retour est l'int du ComplexModel - les modèles simples imbriqués sont toujours NULL. –

0

Enfin, je trouve une solution. Les données publiées sur la méthode Create doivent être similaires. comme ceci:

[HttpPost] 
public ActionResult Create(ComplexModel mainModel, SimpleModel nestedModel, SimpleModel2 nested2Model) 
{ 
    if (ModelState.IsValid) 
    { 
     var main = mainModel; 
     var nested1 = nestedModel; 
     var nested2 = nested2Model; 
    } 

    return View(); 
} 

Les paramètres imbriqués ne sont pas null lorsque les modèles sont liés à des vues partielles. Si utilisé dans le formulaire principal par le modèle principal que les valeurs sont dans l'instance du modèle principal. J'ai aussi changé IEnumerable<string>-IList<string> puis a rendu les valeurs de chaîne avec

for (int i = 0; i < Model.Strings.Count; i++) 
{ %> 
    <%: Html.EditorFor(m => m.Strings[i])%> 
<% } 

Merci à tous