2016-11-30 1 views
2

J'ai créé un Voir modèle appelé CompetitionRoundModel qui est partiellement produit ci-dessous:Problème avec le modèle de liaison

public class CompetitionRoundModel 
{ 
    public IEnumerable<SelectListItem> CategoryValues 
    { 
     get 
     { 
      return Enumerable 
       .Range(0, Categories.Count()) 
       .Select(x => new SelectListItem 
       { 
        Value = Categories.ElementAt(x).Id.ToString(), 
        Text = Categories.ElementAt(x).Name 
       }); 
     } 
    } 

    [Display(Name = "Category")] 
    public int CategoryId { get; set; } 

    public IEnumerable<Category> Categories { get; set; } 

    // Other parameters 
} 

J'ai structuré le modèle de cette façon parce que je dois remplir un menu déroulant en fonction de la valeur stockée dans CategoryValues. Donc, pour moi je:

@using (Html.BeginForm()) 
{ 
    <div class="form-group"> 
     @Html.LabelFor(model => model.CategoryId, htmlAttributes: new { @class = "control-label col-md-2" }) 
     <div class="col-md-10"> 
      @Html.DropDownListFor(model => model.CategoryId, Model.CategoryValues, new { @class = "form-control" }) 
      @Html.ValidationMessageFor(model => model.CategoryId, "", new { @class = "text-danger" }) 
     </div> 
    </div> 
    // Other code goes here 
} 

J'ai choisi model.CategoryId dans la méthode DropDownListFor() puisque je veux lier la valeur sélectionnée à CategoryId. Je ne me soucie vraiment pas de CategoryValues, j'en ai juste besoin pour peupler le DropDown.

Mon problème est maintenant que quand mon contrôleur reçoit les valeurs pour mon modèle dans la méthode d'action, CategoryValues est nul qui fait le système pour lancer une ArgumentNullException (la ligne qui est en surbrillance est la ligne return Enumerable.

I ont même essayé [Bind(Exclude="CategoryValues")] mais aucun changement. toute aide serait appréciée.

+0

Merci @StephenMuecke. Votre solution a fonctionné. Je ne sais pas comment marquer votre commentaire comme une «réponse» ici pour que vous puissiez prendre le crédit. –

Répondre

1

Votre pas (et ne devrait pas être) la création de contrôles de formulaire pour chaque propriété de chaque Category dans votre collection IEnumerable<Category> donc dans votre méthode POST, la valeur de Categories est null (il ne fait jamais initialisé). Dès que vous essayez CategoryValues et l'exception est levée par votre ligne de code .Range(0, Categories.Count()) dans le getter.

Modifier vous voir le modèle pour donner CategoryValues simple Geter/setter, et supprimer la Categories propriété

public class CompetitionRoundModel 
{ 
    public IEnumerable<SelectListItem> CategoryValues { get; set; } 
    [Display(Name = "Category")] 
    public int CategoryId { get; set; } 
    .... // Other properties 
} 

et alimenter le SelectList dans les méthodes de régulation, par exemple

var categories db.Categories; // your database call 
CompetitionRoundModel model = new CompetitionRoundModel() 
{ 
    CategoryValues = categories.Select(x => new SelectListItem() 
    { 
     Value = x.Id.ToString(), 
     Text = x.Name 
    }, 
    .... 
}; 
return View(model); 

ou bien

CompetitionRoundModel model = new CompetitionRoundModel() 
{ 
    CategoryValues = new SelectList(categories, "Id", "Name"), 

Non te aussi que si vous retournez la vue (parce que ModelState est invalide, vous devez repeupler la valeur de CategoryValues (référez-vous à The ViewData item that has the key 'XXX' is of type 'System.Int32' but must be of type 'IEnumerable' pour plus de détails)

0

depuis CategoryValues juste la goutte remplit vers le bas, il ne sera jamais poster sur le serveur et vous devrez reconstruire la liste de la base de données avant en l'utilisant dans l'opération GET ou POST La propriété CategoryId est la valeur sera affiché sur le serveur à partir du DropDownList.