10

I'm close to giving up on this mvc app for today!!

I'm following the Mvc Music Store Tutorial and I'm stuck on page 54.

this is the error I'm getting:

System.NullReferenceException: Object reference not set to an instance of an object.

The error occurs in the third paragraph block (dropdownlist) in the following code:

<%@ Import Namespace ="MvcMovies1" %>
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MvcMovies1.Models.Album>" %>

<p>
    <%: Html.LabelFor(model => model.Title) %>
    <%: Html.TextAreaFor(model => model.Title) %>
    <%: Html.ValidationMessageFor(model => model.Title) %>
</p>

<p>
    <%: Html.LabelFor(model => model.Price) %>
    <%: Html.TextAreaFor(model => model.Price) %>
    <%: Html.ValidationMessageFor(model => model.Price) %>
</p>

<p>
    <%: Html.LabelFor(model => model.AlbumArtUrl) %>
    <%: Html.TextAreaFor(model => model.AlbumArtUrl) %>
    <%: Html.ValidationMessageFor(model => model.AlbumArtUrl) %>
</p>

<p>
    <%: Html.LabelFor(model => model.Artist) %>
    <%: Html.DropDownList("ArtistId", new SelectList(ViewData["Artists"] as IEnumerable, "ArtistId", "Name", Model.ArtistId)) %>
</p>

<p>
    <%: Html.LabelFor(model => model.Genre) %>
    <%: Html.DropDownList("GenreId", new SelectList(ViewData["Genres"] as IEnumerable, "GenreId", "Name", Model.GenreId)) %>
</p>

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

This ascx file is contained within an Edit.aspx file:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MvcMovies1.ViewModels.StoreManagerViewModel>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Edit
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<form id="form1" runat="server">
    <h2>Edit</h2>
    <% using (Html.BeginForm())
       { %>
      <%: Html.ValidationSummary(true)%>

    <fieldset>
      <legend>Edit Album</legend>
      <%: Html.EditorFor(model => model.Album,
          new { Artists = Model.Artists, Genres = Model.Genres }) %>

          <p><input type="submit" value="Save" /></p>


    </fieldset>

      <% } %>
      </form>
</asp:Content>

I realise there's a lot of code there but if anyone can see something obvious that I am doing wrong I'd be very grateful.

EDIT

StoreManagerController.cs (Edit)

 public ActionResult Edit(int id)
    {
        var viewModel = new StoreManagerViewModel
        {
            Album = storeDB.Albums.SingleOrDefault(a => a.AlbumId == id),
            Genres = storeDB.Genres.ToList(),
            Artists = storeDB.Artists.ToList()
        };

        return View(viewModel);
    }

Andddd..StoreManagerViewModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MvcMovies1.Models;

namespace MvcMovies1.ViewModels
{
    public class StoreManagerViewModel
    {
        public Album Album { get; set; }
        public List<Artist> Artists { get; set; }
        public List<Genre> Genres { get; set; }
    }
}

Again I realise i called it MvcMovies1, this was a typo but everything is marked up accordingly.

109221793
  • 15,397
  • 37
  • 100
  • 157
  • 4
    Can you post your action in your controller as well. Are you setting ViewData["Artists"] in the controller? – lancscoder Oct 20 '10 at 15:53
  • Hi Simon G. I have posted the requested code. Thanks for the reply. – 109221793 Oct 20 '10 at 15:59
  • Can you put a breakpoint on that line and check all the properties for nulls? – Rup Oct 20 '10 at 16:10
  • Possible duplicate of [What is a NullReferenceException, and how do I fix it?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – tom redfern Jan 11 '17 at 10:27

6 Answers6

7

Does Album have an ArtistId since in that line you are calling Model.ArtistId and if Album doesn't have that property on it you will get a null reference exception. That's because the Model is a shorthand for the object that is strongly typed to your view, which happens to be Album in your case.

There is no where in your above code where you are setting the ViewData["Artists"]. Are you setting that anywhere since that could be your issue too.

EDIT

Set the ViewData in the action and it should work:

public ActionResult Edit(int id)
{
     var viewModel = new StoreManagerViewModel
     {
         Album = storeDB.Albums.SingleOrDefault(a => a.AlbumId == id),
         Genres = storeDB.Genres.ToList(),
         Artists = storeDB.Artists.ToList()
     };

     ViewData["Artists"] = storeDB.Artists.ToList();
     ViewData["Genres"] = storeDB.Genres.ToList();

     return View(viewModel);
 }
amurra
  • 14,431
  • 4
  • 65
  • 85
  • 1
    But since the model is strongly typed wouldn't the page not compile if ArtistId was missing rather than throw a null reference exception? – Rup Oct 20 '10 at 16:19
  • Hi amurra...I think it's the ViewData["Artists"] this is my issue. I'm only learning Mvc so I have literally followed what was on the tutorial so I'm stumped! – 109221793 Oct 20 '10 at 16:23
  • @Rup - I believe only if you are compiling the views will it show up then, otherwise it would be found during runtime – amurra Oct 20 '10 at 16:41
  • @amurra..thanks for the post. Just tried it there but still the same error in the same place. I suppose that's something eliminated all the same. – 109221793 Oct 20 '10 at 16:50
  • @TaraWalsh - if you hover over the exception in visual studio what is actually causing the null pointer? Is Model.ArtistId null? – amurra Oct 20 '10 at 16:53
  • 1
    @amurra Yes, it'd be at runtime when you try to load the page but it would still be a compile error ("Model does not have property AlbumId" or similar) not a null reference exception. – Rup Oct 20 '10 at 18:11
6

First you need to add properties in your view model to hold selected artist and selected genre:

public class StoreManagerViewModel
{
    public Album Album { get; set; }
    public int? SelectedArtistId { get; set; }
    public List<Artist> Artists { get; set; }
    public int? SelectedGenreId { get; set; }
    public List<Genre> Genres { get; set; }
}

Then in your Edit.aspx view instead of:

<%: Html.EditorFor(model => model.Album,
    new { Artists = Model.Artists, Genres = Model.Genres }) %>

You could simply:

<%: Html.EditorForModel() %>

and in your editor template ~/Views/Home/EditorTemplates/Album.ascx:

<%@ Import Namespace ="MvcMovies1" %>
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MvcMovies1.Models.Album>" %>

<p>
    <%: Html.LabelFor(model => model.Title) %>
    <%: Html.TextAreaFor(model => model.Title) %>
    <%: Html.ValidationMessageFor(model => model.Title) %>
</p>

<p>
    <%: Html.LabelFor(model => model.Price) %>
    <%: Html.TextAreaFor(model => model.Price) %>
    <%: Html.ValidationMessageFor(model => model.Price) %>
</p>

<p>
    <%: Html.LabelFor(model => model.AlbumArtUrl) %>
    <%: Html.TextAreaFor(model => model.AlbumArtUrl) %>
    <%: Html.ValidationMessageFor(model => model.AlbumArtUrl) %>
</p>

and in your editor template ~/Views/Home/EditorTemplates/StoreManagerViewModel:

<%@ Import Namespace ="MvcMovies1" %>
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MvcMovies1.ViewModels.StoreManagerViewModel>" %>

<%: Html.EditorFor(model => model.Album) %>

<p>
    <%: Html.LabelFor(model => model.SelectedArtistId) %>
    <%: Html.DropDownListFor(model => model.SelectedArtistId, new SelectList(Model.Artists, "ArtistId", "Name")) %>
</p>

<p>
    <%: Html.LabelFor(model => model.SelectedGenreId) %>
    <%: Html.DropDownListFor(model => model.SelectedGenreId, new SelectList(Model.Genres, "GenreId", "Name")) %>
</p>

<div>
    <%: Html.ActionLink("Back to List", "Index") %>
</div>
Darin Dimitrov
  • 960,118
  • 257
  • 3,196
  • 2,876
  • Hi Darin, you seem to know your stuff but one thing I don't understand is why the Album.ascx file is now broken down into two different files? – 109221793 Oct 20 '10 at 16:35
  • 1
    Because for better separation of concerns the Album editor template should only care about album properties and not Genres and Artists which are dissociated. It also avoids you working with ugly ViewState and magic strings and casting to IEnumerable, it is always preferable to work with strong typing. – Darin Dimitrov Oct 20 '10 at 16:36
  • Hmm, okay. In the tutorial you see the html textboxes, labels, dropdownlists, etc are all in the one file. I'd like to follow that as closely as I can. If I were to merge the above two into one, would that be okay to work with? – 109221793 Oct 20 '10 at 16:41
  • @TaraWalsh, for me it's totally unacceptable to use ViewData and perform type casts in a view. So you can do whatever you want, I just gave my two cents. – Darin Dimitrov Oct 20 '10 at 16:44
1

problem:

Object reference not set to an instance of an object

Solution:

pubblic ActionResult yourDetails()
{
     List<YourEntityName> PropertyName= new List<YourEntityName>();
     list = db.PropertyName.ToList();
     return View(list);
}

YourEntityName Mean your Table Name i.e PassengerDetial

PropertyName Mean your Class pubblic property i.e PassengerDetails

pubblic Class PassengerDetailContext : DbContext 
{
  pubblic DbSet<PassengerDetail>  passegerDetails {get;set;}
}

List<PassengerDetail> passegerDetails = new List<PassengerDetail>();
list = db.passegerDetails.ToList();
return View(list);
demo
  • 5,376
  • 12
  • 55
  • 130
1

You are simply not setting ViewData["Artists"] and ViewData["genres"] as I can see from your action method.

Make sure you are setting these values somewhere during lifetime of a request if you want to use them in your view.

Nathanbe
  • 15
  • 7
Muhammad Adeel Zahid
  • 16,658
  • 13
  • 86
  • 147
  • Isn't it merged into the ViewData by the `EditorFor` call? She's passing it in the additionalViewData parameter http://msdn.microsoft.com/en-us/library/ff406462.aspx – Rup Oct 20 '10 at 16:26
  • 9
    please spell 'you' instead of 'u'. this is not twitter. – automagic Oct 20 '10 at 16:28
1

Have you tried casting to List and List instead of IEnumerable?

bmancini
  • 2,008
  • 15
  • 20
0

Had the same error while trying to run migration (update-database). had 2 projects namely ViewProject and DBcontextProject.

my problem was that I made ViewProject a start-up project and ran migration on DBcontextProject.

The solution was to make DBcontextProject a start-up project and run migration on DBcontextProject.

Stanley Mohlala
  • 4,024
  • 1
  • 8
  • 18