2012-04-30 2 views
0

Ce que j'essaie de faire est de créer un objet SubCategory. Pour ce faire, j'ai créé un viewmodel qui fournira ma vue avec les données de nescesarry (y compris un objet de catégorie auquel la sous-catégorie sera liée.)ViewModel est null lors de la soumission du formulaire

Lorsque je poste mon formulaire, le viewmodel est renvoyé à mon contrôleur mais toutes les propriétés de ma sous-catégorie et ma valeur sélectionnée dans une liste déroulante sont nulles.

qu'est-ce que je fais mal? : S

Vue:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.master" Inherits="System.Web.Mvc.ViewPage<SkyLearn.Areas.Categories.Models.CategoryViewModel>" %> 

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

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

<h2>Create</h2> 

<script src="<%: Url.Content("~/Scripts/jquery.validate.min.js") %>" type="text/javascript"></script> 
<script src="<%: Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js") %>" type="text/javascript"></script> 

<form action="" method="post" enctype="multipart/form-data"> 
    <%: Html.ValidationSummary(true) %> 
    <fieldset> 
     <legend>SubCategory</legend> 

     <div class="editor-label"> 
      <%: Html.LabelFor(model => model.subcategory.Title) %> 
     </div> 
     <div class="editor-field"> 
      <%: Html.EditorFor(model => model.subcategory.Title)%> 
      <%: Html.ValidationMessageFor(model => model.subcategory.Title)%> 
     </div> 

     <div class="editor-label"> 
      <%: Html.LabelFor(model => model.subcategory.Icon)%> 
     </div> 
     <div class="editor-field"> 
      <input type="file" name="icon" id="icon"/> 
     </div> 

     <%: Html.DropDownListFor(selectedcategory => Model.selectedCategory, Model.categories) %> 

     <div class="editor-label"> 
      <%: Html.LabelFor(model => model.subcategory.Description)%> 
     </div> 
     <div class="editor-field"> 
      <%: Html.EditorFor(model => model.subcategory.Description)%> 
      <%: Html.ValidationMessageFor(model => model.subcategory.Description)%> 
     </div> 

     <p> 
      <input type="submit" value="Create" /> 
     </p> 
    </fieldset> 
</form> 

<div> 
    <%: Html.ActionLink("Back to List", "Index") %> 
</div> 

</asp:Content> 

<asp:Content ID="Content3" ContentPlaceHolderID="SideContent" runat="server"> 
</asp:Content> 

Controller:

[Authorize(Roles = "administrator")] 
     [HttpPost] 
     public ActionResult Create(CategoryViewModel viewmodel, HttpPostedFileBase Icon) 
     { 
      SubCategory subcategory = viewmodel.subcategory; 

      subcategory.Category = categorycontroller.getCategoryByName(viewmodel.selectedCategory); 

      if (Icon != null && Icon.ContentLength > 0) 
      { 
       // extract only the filename 
       var fileName = Path.GetFileName(Icon.FileName); 
       // store the file inside ~/App_Data/uploads folder 
       var path = Path.Combine(Server.MapPath("../../Content/icons/"), fileName); 
       Icon.SaveAs(path); 
       subcategory.Icon = fileName; 
      } 

      if (ModelState.IsValid) 
      { 
       db.subcategories.Add(subcategory); 
       db.SaveChanges(); 
       return RedirectToAction("Index"); 
      } 

      return View(subcategory); 
     } 

ViewModel:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Data.Entity; 
using System.Web.Mvc; 

namespace SkyLearn.Areas.Categories.Models 
{ 
    public class CategoryViewModel 
    { 
     public List<SelectListItem> categories; 
     public SubCategory subcategory; 
     public string selectedCategory; 

     public CategoryViewModel() 
     { 
      categories = new List<SelectListItem>(); 
      subcategory = new SubCategory(); 
      selectedCategory = ""; 
     } 
    } 
} 

la viewmodel contient une liste de catégories que la sous-catégorie im essayant de créer peut être lié à. il contient également un objet de sous-catégorie que je peux utiliser pour créer la sous-catégorie. et la dernière propriété est une chaîne que je veux utiliser pour lier le choix dans la liste déroulante.

+0

Peut être le post: http://stackoverflow.com/questions/9513385/creating-a-dropdown-in-mvc3-c-sharp-with-viewmodel-and-easy-model-binding-on-pos/ 9513747 # 9513747, vous aider à obtenir avec la liaison de modèle par défaut. –

+0

J'ai déjà lu la plupart des articles sur le sujet. Je peux me tromper mais je pense que j'ai déjà des champs de saisie (html.editorfor) et en utilisant les noms corrects pour le lier. Je suis un peu nouveau à MVC donc je pourrais être complètement faux – AronChan

+0

Encore une fois, je dois admettre honteusement que j'ai oublié quelque chose d'aussi simple que d'ajouter Get; Ensemble; tout fonctionne maintenant. soupir.merci pour l'aide – AronChan

Répondre

1

Le SelectListItem d'ASP.Net MVC3 ne se comporte pas comme prévu. En outre, essayez Html.DropDownListFor() plutôt que Html.EditorFor() pour créer votre liste déroulante.

Dans le ViewModel:

public IList<string> PossibleValues {get; set;} 
public string SelectedValue {get; set;} 

charge les valeurs dans PossibleValues ​​dans le constructeur de votre ViewModel.

Dans la vue:

@Html.DropDownListFor(x => x.SelectedValue, new SelectList(Model.PossibleValues)) 

Cela autogenerate votre liste déroulante et le lier à votre modèle. Vous pouvez également passer des valeurs par défaut et d'autres personnalisations dans cette fonction d'assistance Html, si vous le souhaitez.

Saving D'autres valeurs Vous pouvez enregistrer d'autres valeurs, les valeurs que l'utilisateur ne doit pas avoir la possibilité de modifier, mais qui ne sont pas à mission critique si l'utilisateur ne modifie, avec

@Html.HiddenFor(m => m.RememberThisValue); 

Rappelez-vous, cette valeur est cachée de l'affichage, mais peut toujours être édité sur le DOM et posté avec tout ce que l'utilisateur veut. Assurez-vous de vous protéger contre l'injection de valeurs malveillantes en vérifiant les valeurs masquées POST. Stockez tout ce qui est important côté serveur, transmettez une clé de hachage/privée à l'utilisateur via votre modèle et implémentez un dictionnaire de session statique pour stocker ces petites informations.

+0

J'utilise le Html.DropDownListFor. également la seule source acceptée par l'assistant dropdownlist est la liste selectItem. cela provoquera donc une erreur. existe-t-il un autre moyen de lier le reste de mes propriétés au modèle? – AronChan

+0

J'ai réussi à faire publier la valeur sélectionnée sur submit grâce à votre réponse. Il est toujours un mystère pour moi comment je peux obtenir le reste de mon viewmodel peuplé avec les bonnes valeurs de la vue. des commentaires à ce sujet? – AronChan

+0

Oui, vous avez raison. J'ai corrigé mon exemple et ajouté une réponse sur le reste de vos valeurs. – Khelvaster

Questions connexes