locked
Why am i getting a null value when binding DDL? RRS feed

  • Question

  • User-1526035670 posted

    Hi

    A dropdown which has its binding data done from code-behind is causing the error 

    Exception Details: System.ArgumentNullException: Value cannot be null.
    Parameter name: items

    In debug mode i can see its null but cant understand why? Is there something i have done incorrectly?

    I have left some properties out and any relationships but can provide if you feel it helps!

    public ActionResult Index()
            {
                var categories = GetCats();
                var viewModel = new ViewModels.CustomProductModels
                {
                    Categories = categories
                };
    
                return View("Index", viewModel);
            }
    
            private List<Category> GetCats()
            {
                var cats = new List<Category>();
    
                cats.Add(new Category{Id=1, Title = "Cat 1"});
                cats.Add(new Category{Id=2, Title = "Cat 2"});
                cats.Add(new Category { Id = 3, Title = "Cat 3" });
                cats.Add(new Category { Id = 4, Title = "Cat 4" });
    
                return cats;
            }
    
    public class CustomProductModels
        {
            public IEnumerable<Category> Categories { get; set; }
    // Other properties for product }

    My HTML is 

    @Html.DropDownListFor(c => c.Product.CategoryId, new SelectList(Model.Categories, "Id", "Text"), "Select Category", new { @class = "form-control" })
    
    Monday, May 17, 2021 1:52 PM

Answers

  • User475983607 posted

    That didnt work either..... Judging by your replies there must be a problem elsewhere which i think i will need to dig a little further.....

    Keep in mind, the bug we pointed out is an actual bug in your code that should be fixed.  Unfortunately, you did not share all the relevant code so it is near impossible to figure out what else is wrong.  My best guess is the error happens on an HTTP Post because you forgot to populate the Categories collection.

        public class CustomProductModels
        {
            public IEnumerable<Category> Categories { get; set; }
            public ProductModel Product { get; set; }
        }
        public class ProductModel
        {
            public int CategoryId { get; set; }
        }
        public class Category
        {
            public int Id { get; set; }
            public string Title { get; set; }
        }
        public class GeneralController : Controller
        {
            [HttpGet]
            public ActionResult Index()
            {
                var categories = GetCats();
                var viewModel = new CustomProductModels
                {
                    Categories = categories
                };
    
                return View("Index", viewModel);
            }
            [HttpPost]
            public ActionResult Index(MvcDemo.Controllers.CustomProductModels model)
            {
                var categories = GetCats();
                var viewModel = new CustomProductModels
                {
                    Categories = categories,
                    Product = new ProductModel()
                    {
                        CategoryId = model.Product.CategoryId
                    }
                };
                return View(viewModel);
            }
    
    
            private List<Category> GetCats()
            {
                var cats = new List<Category>();
    
                cats.Add(new Category { Id = 1, Title = "Cat 1" });
                cats.Add(new Category { Id = 2, Title = "Cat 2" });
                cats.Add(new Category { Id = 3, Title = "Cat 3" });
                cats.Add(new Category { Id = 4, Title = "Cat 4" });
    
                return cats;
            }
        }
    @model MvcDemo.Controllers.CustomProductModels
    
    @{
        ViewBag.Title = "Index";
    }
    
    <h2>Index</h2>
    
    
    @using (Html.BeginForm()) 
    {
    
        <div>
            @Html.DropDownListFor(c => c.Product.CategoryId, new SelectList(Model.Categories, "Id", "Title"), "Select Category", new { @class = "form-control" })
        </div>
        <div>
            <input id="Submit1" type="submit" value="submit" />
        </div>
    
    }

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, May 17, 2021 5:55 PM

All replies

  • User475983607 posted

    Hi

    A dropdown which has its binding data done from code-behind is causing the error 

    Exception Details: System.ArgumentNullException: Value cannot be null.
    Parameter name: items

    In debug mode i can see its null but cant understand why? Is there something i have done incorrectly?

    I have left some properties out and any relationships but can provide if you feel it helps!

    public ActionResult Index()
            {
                var categories = GetCats();
                var viewModel = new ViewModels.CustomProductModels
                {
                    Categories = categories
                };
    
                return View("Index", viewModel);
            }
    
            private List<Category> GetCats()
            {
                var cats = new List<Category>();
    
                cats.Add(new Category{Id=1, Title = "Cat 1"});
                cats.Add(new Category{Id=2, Title = "Cat 2"});
                cats.Add(new Category { Id = 3, Title = "Cat 3" });
                cats.Add(new Category { Id = 4, Title = "Cat 4" });
    
                return cats;
            }
    
    public class CustomProductModels
        {
            public IEnumerable<Category> Categories { get; set; }
            // Other properties for product
        }

    My HTML is 

    @Html.DropDownListFor(c => c.Product.CategoryId, new SelectList(Model.Categories, "Id", "Text"), "Select Category", new { @class = "form-control" })
    

    The SelectList  constructor expects a "Text" property in the Category class.  You defined a "Title" property but not "Text".  Also, you did not share all the relevant code and the code you have shared is questionable.  There can be other issues the design.

    Monday, May 17, 2021 2:09 PM
  • User-1526035670 posted

    Hi

    I'm not to sure which text property you are referring to as I believe I've passed it in? The first parameter is the ID then a new select list where I pass in the text as well?

    Sure I can provide you more code. The HTML is pretty much all there except for the using statements. Is there anything you want me to paste in particular?

    Thanks

    Monday, May 17, 2021 2:18 PM
  • User-474980206 posted

    The error is very clear. It looks you are just copy and pasting code, not reading the docs.  In the line

    Html.DropDownListFor(c => c.Product.CategoryId, new SelectList(Model.Categories, "Id", "Text"), "Select Category", new { @class = "form-control" })

    the binder is complaining that the Text property values of Model.Categories are null.  As suggested, it appears you wanted to use title.

    Html.DropDownListFor(c => c.Product.CategoryId, new SelectList(Model.Categories, "Id", "Title"), "Select Category", new { @class = "form-control" })
    Monday, May 17, 2021 2:24 PM
  • User-1526035670 posted

    That didnt work either..... Judging by your replies there must be a problem elsewhere which i think i will need to dig a little further.....

    Monday, May 17, 2021 4:05 PM
  • User475983607 posted

    That didnt work either..... Judging by your replies there must be a problem elsewhere which i think i will need to dig a little further.....

    Keep in mind, the bug we pointed out is an actual bug in your code that should be fixed.  Unfortunately, you did not share all the relevant code so it is near impossible to figure out what else is wrong.  My best guess is the error happens on an HTTP Post because you forgot to populate the Categories collection.

        public class CustomProductModels
        {
            public IEnumerable<Category> Categories { get; set; }
            public ProductModel Product { get; set; }
        }
        public class ProductModel
        {
            public int CategoryId { get; set; }
        }
        public class Category
        {
            public int Id { get; set; }
            public string Title { get; set; }
        }
        public class GeneralController : Controller
        {
            [HttpGet]
            public ActionResult Index()
            {
                var categories = GetCats();
                var viewModel = new CustomProductModels
                {
                    Categories = categories
                };
    
                return View("Index", viewModel);
            }
            [HttpPost]
            public ActionResult Index(MvcDemo.Controllers.CustomProductModels model)
            {
                var categories = GetCats();
                var viewModel = new CustomProductModels
                {
                    Categories = categories,
                    Product = new ProductModel()
                    {
                        CategoryId = model.Product.CategoryId
                    }
                };
                return View(viewModel);
            }
    
    
            private List<Category> GetCats()
            {
                var cats = new List<Category>();
    
                cats.Add(new Category { Id = 1, Title = "Cat 1" });
                cats.Add(new Category { Id = 2, Title = "Cat 2" });
                cats.Add(new Category { Id = 3, Title = "Cat 3" });
                cats.Add(new Category { Id = 4, Title = "Cat 4" });
    
                return cats;
            }
        }
    @model MvcDemo.Controllers.CustomProductModels
    
    @{
        ViewBag.Title = "Index";
    }
    
    <h2>Index</h2>
    
    
    @using (Html.BeginForm()) 
    {
    
        <div>
            @Html.DropDownListFor(c => c.Product.CategoryId, new SelectList(Model.Categories, "Id", "Title"), "Select Category", new { @class = "form-control" })
        </div>
        <div>
            <input id="Submit1" type="submit" value="submit" />
        </div>
    
    }

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, May 17, 2021 5:55 PM
  • User287926715 posted

    Hi JamieP1,

    @Html.DropDownListFor(c => c.Product.CategoryId, new SelectList(Model.Categories, "Id", "Text"), "Select Category", new { @class = "form-control" })

    According to the codes you provided, your List<Category> only has two attributes: ID and Title and no Text attribute. After I changed Text to Ttile, it can run normally.

    HTML:

    @Html.DropDownListFor(c => c.Product.CategoryId, new SelectList(Model.Categories, "Id", "Title"), "Select Category", new { @class = "form-control" })

    Result:

    Best Regards,

    ChaoDeng

    Tuesday, May 18, 2021 6:07 AM
  • User-1526035670 posted

    Thanks everyone. It seems there was another dll within the project that was offsetting the route. Eventually adjusting it fixed the problem.

    Tuesday, May 18, 2021 1:02 PM