web-dev-qa-db-fra.com

Remplir DropDownList dans MVC 5

Voici mon code pour mon AddNewProductViewModel

using AccessorizeForLess.Data;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web;

namespace AccessorizeForLess.ViewModels
{
    public class AddNewProductViewModel
    {
        public string Name { get; set; }

        [DataType(DataType.MultilineText)]
        public string Description { get; set; }

        public decimal Price { get; set; }

        public string AltText { get; set; }

        public int Quantity { get; set; }

        public string ImagePath { get; set; }

        public HttpPostedFileBase Image { get; set; }

        public List<ProductCategory> Category { get; set; }
    }
}

Voici mon Créer méthode dans mon contrôleur

[HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Create(AddNewProductViewModel model)
        {
            ProductImageViewModel image = new ProductImageViewModel() { ImagePath = "/Content/ProductImages/" + model.Image.FileName, AltText = model.AltText };
            ProductImage newImage = new ProductImage() { ImagePath = image.ImagePath, AltText = image.AltText };
            entities.ProductImages.Add(newImage);
            await entities.SaveChangesAsync();
            int ImageId = newImage.ProductImageId;

            Product product = new Product()
            {
                ProductImageId = ImageId,
                ProductName = model.Name,
                ProductDescription = model.Description,
                ProductPrice = model.Price,
                Quantity = model.Quantity
                CategoryID = model.
            };

            string file = model.Image.FileName;
            string path = Server.MapPath(@"~/Content/ProductImages");
            string fullPath = path + @"\" + file;
            try
            {
                model.Image.SaveAs(path + @"\" + file);

                if (ModelState.IsValid)
                {
                    entities.Products.Add(product);
                    await entities.SaveChangesAsync();
                    return RedirectToAction("Create");
                }
            }
            catch (Exception ex)
            {
                ViewBag.Message = ex.ToString();
            }
           //ViewBag.ProductImageId = new SelectList(entities.ProductImages, "ProductImageId", "ImagePath", product.ProductImageId);
            return View("Create");
        }

Et maintenant, où je tente de peupler ma liste déroulante à mon avis:

<div class="form-group">
            @Html.LabelFor(model => model.Category, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownListFor(model => model.Category.Id, new SelectList(Model.Category,"Value","Text"), "- Please Select -")
                @Html.ValidationMessageFor(model => model.Category)
            </div>
        </div>

Et c'est l'erreur que j'obtiens:

CS0411: Les arguments de type pour la méthode 'System.Web.Mvc.Html.SelectExtensions.DropDownListFor (System.Web.Mvc.HtmlHelper, System.Linq.Expressions.Expression>, System.Collections.Generic.IEnumerable, Object)' ne peut pas être déduit de l'utilisation. Essayez de spécifier le type arguments explicitement.

MODIFIER

Voici le nouveau - AddNewProductViewModel

using AccessorizeForLess.Data;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web;

namespace AccessorizeForLess.ViewModels
{
    public class AddNewProductViewModel
    {
        public string Name { get; set; }

        [DataType(DataType.MultilineText)]
        public string Description { get; set; }

        public decimal Price { get; set; }

        public string AltText { get; set; }

        public int Quantity { get; set; }

        public string ImagePath { get; set; }

        public HttpPostedFileBase Image { get; set; }

        public ProductCategory Category { get; set; }

        public int SelectedCategoryId { get; set; }

        public List<ProductCategory> Categories { get; set; }
}
}

Et ma tentative de mise à jour d'une liste déroulante

<div class="form-group">
            @Html.LabelFor(model => model.Category, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownListFor(model => model.SelectedCategoryId,
                 new SelectList(Model.Categories, "CategoryId", "CategoryName"), "- Please Select -")
                @Html.ValidationMessageFor(model => model.Category)
            </div>
        </div>

Maintenant, je reçois une exception NullReferenceException sur cette ligne

@Html.DropDownListFor(model => model.SelectedCategoryId,

Compte tenu de mon code, quelqu'un peut-il me montrer ce que je fais de mal ici, cela me pose problème depuis la nuit dernière.

4
PsychoCoder

J'ai résolu le problème (merci à tous pour les conseils). Ceci est pour quiconque peut avoir des problèmes comme je l'étais.

J'ai modifié ma méthode Create pour qu'elle ressemble à ceci:

// GET: /Products/Create
public ActionResult Create()
{
    var p = new AddNewProductViewModel();
    p.Categories = entities.ProductCategories.ToList();
    return View(p);
}

Mon AddNewProductViewModel ressemble à ceci:

using AccessorizeForLess.Data;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web;

namespace AccessorizeForLess.ViewModels
{
    public class AddNewProductViewModel
    {
        public string Name { get; set; }

        [DataType(DataType.MultilineText)]
        public string Description { get; set; }

        public decimal Price { get; set; }

        public string AltText { get; set; }

        public int Quantity { get; set; }

        public HttpPostedFileBase Image { get; set; }

        public int SelectedCategoryId {get;set;}
        public List<ProductCategory> Categories { get; set; }
        public ProductCategory Category { get; set; }
    }
}

Le à mon avis:

<div class="form-group">
    @Html.LabelFor(model => model.SelectedCategoryId, "Category",new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.DropDownListFor(model => model.SelectedCategoryId, new SelectList(Model.Categories, "CategoryId", "CategoryName"), "- Please Select -")
        @Html.ValidationMessageFor(model => model.SelectedCategoryId)
    </div>
</div>

Merci à tous pour l'aide :)

6
PsychoCoder

Premièrement, je modifierais votre ViewModel pour inclure une SelectedCategoryId et je changerais vos options en Categories.

Sans voir le code de votre get je suis assumbing ProductCategory est quelque chose comme ce qui suit:

public class ProductCategory {
  public int Id {get;set;}
  public string Name { get;set;}
}

Votre marge de rasoir deviendraient-ils:

<div class="form-group">
     @Html.LabelFor(model => model.Categories, new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownListFor(model => model.SelectedCategoryId, 
            new SelectList(Model.Categories, "Id", "Name"), "- Please Select -")
            @Html.ValidationMessageFor(model => model.Categories)
        </div>
</div>

Le premier paramètre est la catégorie sélectionnée et vos options sont renseignées à partir de Categories.

WorkingFiddle

2
hutchonoid

Utilisez votre contrôleur pour construire la liste, puis appelez la liste à partir de la vue.

Manette:

public static List<SelectListItem> GetDropDown()
    {
        List<SelectListItem> ls = new List<SelectListItem>();
        lm = (call database);
        foreach (var temp in lm)
        {
            ls.Add(new SelectListItem() { Text = temp.name, Value = temp.id });
        }
        return ls;
    }

Appelez le Dropdown:

@Html.DropDownListFor(x => x.Field, PathToController.GetDropDown())
0
pool pro