Click here to Skip to main content
15,900,907 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Hello ! I am trying to implement a select list(DropDownListFor) and a Multi Select List(ListBoxFor) in ASP.NET(MVC5), and i am getting an 'Object reference not set to an instance of an object' exception when i submit the form. I found a bunch of stack overflow articles, that didn't actually helped me me much. I tried a lot of things, but no much of a luck.

Here is a photo of the exception: [Exception Photo,
click me!
]

What I have tried:

Controller:

public ActionResult New()
        {
            List<string> availableImages = new List<string>();
            //here i an getting the path for all the available images from 
            // the database
            foreach (Image contextImage in _context.Images)
            {
                availableImages.Add(contextImage.FullName);
            }
            
            return View("New", new NewProductViewModel(availableImages));
        }


ViewModel:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Mom_Website.Models;

namespace Mom_Website.ViewModels
{
    public class NewProductViewModel
    {
        public int Id { get; set; }

        [Required]
        [StringLength(40)]
        public string Name { get; set; }

        [Required]
        public string Description { get; set; }

        //This is the 'default photo' that will be displayed at the product
        //thumbnail(at the product's index)
        [Required]
        public string ThumbnailImage { get; set; }

        //This property contains the selected photos to be displayed on the
        //Details page of the product
        [Required]
        public IEnumerable<string> SelectedImages { get; set; }

        [Required]
        public int Price { get; set; }

        [Required]
        public int ShippingCost { get; set; }

        [Required]
        public int NumberAvailable { get; set; }

        //this field contains all the available photos on the database
        public IEnumerable<SelectListItem> MultiSelectAvailableImages { get; set; }

        public IEnumerable<SelectListItem> SelectListAvailableImages { get; set; }

        public NewProductViewModel(IEnumerable<string> availableImages)
        {
            this.MultiSelectAvailableImages = new MultiSelectList(availableImages);
            this.SelectListAvailableImages = new SelectList(availableImages);
        }

        public NewProductViewModel()
        {
        }
    }
}


View:

@model Mom_Website.ViewModels.NewProductViewModel

@{
    ViewBag.Title = "New";
}

<h2>New Product</h2>

@using (Html.BeginForm("Save", "Products"))
{
    <div class="form-group">
        @Html.LabelFor(m => m.Name)
        @Html.TextBoxFor(m => m.Name, new { @class = "form-control" })
        @Html.ValidationMessageFor(m => m.Name)
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Description)
        @Html.TextBoxFor(m => m.Description, new { @class = "form-control" })
        @Html.ValidationMessageFor(m => m.Description)
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.NumberAvailable)
        @Html.TextBoxFor(m => m.NumberAvailable, new { @class = "form-control" })
        @Html.ValidationMessageFor(m => m.NumberAvailable)
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Price)
        @Html.TextBoxFor(m => m.Price, new { @class = "form-control" })
        @Html.ValidationMessageFor(m => m.Price)
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.ShippingCost)
        @Html.TextBoxFor(m => m.ShippingCost, new { @class = "form-control" })
        @Html.ValidationMessageFor(m => m.ShippingCost)
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.ThumbnailImage)
        @Html.DropDownListFor(m => m.ThumbnailImage, Model.SelectListAvailableImages, "Select Default Image", new { @class = "form-control" })
        @Html.ValidationMessageFor(m => m.ThumbnailImage)
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.SelectedImages)
        @Html.ListBoxFor(m => m.SelectedImages, Model.MultiSelectAvailableImages, new { @class = "form-control" })
        @Html.ValidationMessageFor(m => m.SelectedImages)
    </div>
    @Html.HiddenFor(m => m.Id)
    @Html.AntiForgeryToken()
    <button type="submit" class="btn btn-primary">Save</button>
}

@section scripts
{
    @Scripts.Render("~/Bundles/jqueryval")
}
Posted
Updated 28-Aug-17 1:19am
v4

This is one of the most common problems we get asked, and it's also the one we are least equipped to answer, but you are most equipped to answer yourself.

Let me just explain what the error means: You have tried to use a variable, property, or a method return value but it contains null - which means that there is no instance of a class in the variable.
It's a bit like a pocket: you have a pocket in your shirt, which you use to hold a pen. If you reach into the pocket and find there isn't a pen there, you can't sign your name on a piece of paper - and you will get very funny looks if you try! The empty pocket is giving you a null value (no pen here!) so you can't do anything that you would normally do once you retrieved your pen. Why is it empty? That's the question - it may be that you forgot to pick up your pen when you left the house this morning, or possibly you left the pen in the pocket of yesterdays shirt when you took it off last night.

We can't tell, because we weren't there, and even more importantly, we can't even see your shirt, much less what is in the pocket!

Back to computers, and you have done the same thing, somehow - and we can't see your code, much less run it and find out what contains null when it shouldn't.
But you can - and Visual Studio will help you here. Run your program in the debugger and when it fails, VS will show you the line it found the problem on. You can then start looking at the various parts of it to see what value is null and start looking back through your code to find out why. So put a breakpoint at the beginning of the method containing the error line, and run your program from the start again. This time, VS will stop before the error, and let you examine what is going on by stepping through the code looking at your values.

But we can't do that - we don't have your code, we don't know how to use it if we did have it, we don't have your data. So try it - and see how much information you can find out!
 
Share this answer
 
Comments
xXxRevolutionxXx 28-Aug-17 5:43am    
First of all, thank you very much that you gave quite some time to write this text for me. Back to the work.

I am programming for about 2 years now, so i have a pretty good idea what debugging is. The think is that everything here is instantiated. It should work, but it doesn't(yes, this is another common phrase on the programming world). The thing is that here breakpoints and e.t.c cannot help me, since the problem is setting up the lists. I did everything by the book(at least i think i did), but i still get this exception.
OriginalGriff 28-Aug-17 5:53am    
The error specifically means that something is null, where it isn;t expected - and there is a good chance that it's in your data, not your code - but we can't tell because we don't have access to both while it's running. So when you set up the lists, look at the data you are using to set them up - something is null and until you find out exactly what, nobody can fix this! :laugh:
xXxRevolutionxXx 29-Aug-17 2:03am    
Accepted your answer.
So.... after a lot of debugging going on here, i must say that the problem was really simple.

First, DO NOT USE a constructor in ANY way when you use model binding. It will destroy your brain on the process. Instead, set the values when you create the instance of the ViewModel on the controller. For example:
ViewModelClass myViewModel = new ViewModelClass();
myViewModel.ThePropertyIWantToSet = SomeData;

This was the root of the problem.

Second, i was mistaken on the save action on the controller. I returned a View after submitting the data there... without passing a ViewModel(of course). I change this:
return View("New"); 
to:

return RedirectToAction("New");


I hope this comment will help people in the future !!
 
Share this answer
 
v3
Comments
Graeme_Grant 28-Aug-17 20:24pm    
Please do not post solutions to your own problems, then flag as answered. This is considered reputation farming and can get you kicked.

Instead, include this update in the Question by clicking on the "Improved question" widget above. Once done, please delete this solution.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900