Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Populate DropDownList in MVC 5

Here is my code for my 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; }
    }
}

Here's my Create method in my controller

[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");
        }

And now where I'm trying to populate my DropDownList in my view:

<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>

And this is the error I'm getting:

CS0411: The type arguments for method 'System.Web.Mvc.Html.SelectExtensions.DropDownListFor(System.Web.Mvc.HtmlHelper, System.Linq.Expressions.Expression>, System.Collections.Generic.IEnumerable, object)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

EDIT

Here's is the new 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; }
}
}

And my updated attempt at a dropdownlist

<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>

Now I'm getting a NullReferenceException on this line

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

Given my code can someone please show me what I'm doing wrong here, I've been struggling with this since last night.

like image 211
PsychoCoder Avatar asked Jul 27 '15 07:07

PsychoCoder


People also ask

How do you bind a static value to a DropDownList in MVC?

Binding MVC DropDownList with Static Values Just add an Html helper for DropDownList and provide a static list of SelectListItem. The values added as SelectListItem will be added and displayed in the DropDownList. In this way, you do not need to add anything to Controller Action.


2 Answers

I solved the issue (thanks to everyone for the tips). This is for anyone who may be having issues like I was.

I changed my Create method to look like so:

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

My AddNewProductViewModel looks like so:

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; }
    }
}

The in my view:

<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>

Thanks for the help everyone :)

like image 82
PsychoCoder Avatar answered Sep 23 '22 20:09

PsychoCoder


First I would change your ViewModel to include a SelectedCategoryId and I would change your options to be Categories.

Without seeing the code for your get I am assumbing ProductCategory is something like the following:

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

Your razor mark-up would them become:

<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>

The first parameter is the selected catgegory and your options are populated from Categories.

WorkingFiddle

like image 35
hutchonoid Avatar answered Sep 19 '22 20:09

hutchonoid