How to avoid and fix NullReferenceExceptions in ASP.NET MVC

30 Jul 2015

Quite often people stumble into same problems again and again, and getting a NullReferenceException is the one that occurs most frequently, and frankly, can be quite annoying. This problem happens when writing brand-new ASP.NET MVC code, such as controllers or views, but also when modifying existing code that used to work just fine, but somehow suddenly got broken. Here I want to show you why these exceptions happen and how to fix them, so you can stop wasting your time and do more of the programming that you actually enjoy.

What is NullReferenceException and where can it happen?

NullReferenceException is exactly what it says - it is thrown by .NET Runtime when your code tries to access properties or call methods using empty, or null, reference. It sounds obvious and trite, but finding a place in your code where things went haywire may take some time.

NullReferenceException in .cshtml Razor views

Let’s say you have a UserProfile.cshtml page that displays “Industry” selection drop down list for a logged in user (to put a dropdown on a form see my other article):

@model UserProfileModel

<div class="form-group">
    @Html.LabelFor(m => m.Industry)
    @Html.EnumDropDownListFor(model => model.Industry,
                              Model.Industries,
                              "- Please select your industry -",
                              new { @class = "form-control" })
</div>

and when you hit this page you see the following exception:

Server Error in '/' Application.

Object reference not set to an instance of an object.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

Source Error:

Line 27:                     <div class="form-group">
Line 28:                         @Html.LabelFor(m => m.Industry)
Line 29:                         @Html.EnumDropDownListFor(m => m.Industry,
Line 30:                                                   Model.Industries,
Line 31:                                                   "- Please select your industry -",

Source File: c:\[...]\Views\Profile\UserProfile.cshtml    Line: 29

Stack Trace:

[NullReferenceException: Object reference not set to an instance of an object.]
ASP._Page_Views_Profile_UserProfile_cshtml.Execute() in c:\...\Views\Profile\UserProfile.cshtml:29
System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +271
[... some lines deleted ...]
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +38
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +932
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +188

Believe me or not, this problem trips people over most often. The reason for this exception is that no model is being passed to the view from the controller’s action:

public ActionResult UserProfile() {
    var userModel = GetLoggedInUser();
    //
    // … some more super-serious business logic in here ...
    //
    return View(); // <-- HERE'S THE PROBLEM!
}

That’s why when the view is being rendered, Model variable inside of .cshtml points to null, and trying to access null.FirstName obviously throws a brand spanking new NullReferenceException. To fix this need to pass an instance of the model to the View() call:

public ActionResult UserProfile() {
    var userModel = GetLoggedInUser();
    //
    // … some more super-serious business logic in here ...
    //
    return View(userModel); // <-- JUST PASS THE MODEL HERE, TOO EASY!
}

NullReferenceException when working with database entities

This is a second most-common problem - when loading entities from a database, you cannot always be sure whether an object you’re trying to load or one of its linked entities exists. Say there’s an optional Address object that UserProfile object can be linked to. If you do the following in your code, you’ll get a NullReferenceException when Address is missing:

public int GetUserPostCode(int userId) {
    var user = GetUserFromDb(userId);
    return user.Address.PostCode;
}

In which case the following exception will blow your call stack right up:

Server Error in '/' Application.

Object reference not set to an instance of an object.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

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

Source Error:

Line 55:         public int GetUserPostCode(int userId) {
Line 56:             var user = GetUserFromDb(userId);
Line 57:             return user.Address.PostCode;
Line 58:         }

Source File: c:\...\Controllers\ProfileController.cs    Line: 57

Stack Trace:

[NullReferenceException: Object reference not set to an instance of an object.]
App.Controllers.ProfileController.ViewProfile() in c:\...\Controllers\ProfileController.cs:57
lambda_method(Closure , ControllerBase , Object[] ) +101
System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +59
... some lines skipped...
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +932
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +188


Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.34212

To fix this exception, you need to retrieve data in a safe manner - by checking all the reference types first and avoiding dangerous assumptions that related objects are always going to be present:

public int? GetUserPostCode(int userId) { // Notice that function returns nullable int now
    var user = GetUserFromDb(userId);
    if (user != null && user.Address != null) { // This check will help to avoid NullReferenceExceptions
        return user.Address.PostCode;
    }
    return null;
}

NullReferenceException when calling methods on null

Similarly, calling any functions on a null reference will result in NullReferenceException. Say you are building an auction site, where users can add photos to their listings. There’s class called ‘Listing’ that has a collection of ‘Photos’, and you want users to be able to submit new listings along with the photos in the following manner:

[HttpPost]
public ActionResult NewListing(ListingModel model) {
    var newListing = new ListingDBObject {
        Price = model.Price,
        Title = model.Title,
        ContactNumber = model.ContactNumber
    }

    foreach (var photo in model.Photos) {
        newUser.Photos.Add(new PhotoDBObject { // <- THIS WILL BLOW UP!
            BinaryData = photo.Data;
        });
    }

    //...here goes code that saves new listing to the database
}

Again, you’ll get a brand new NullReferenceException with the following stack trace:

Server Error in '/' Application.

Object reference not set to an instance of an object.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

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

Source Error:

Line 25:
Line 26:    foreach (var photo in model.Photos) {
Line 27:        newUser.Photos.Add(new PhotoDBObject {
Line 58:            BinaryData = photo.Data;

Source File: c:\...\Controllers\ProfileController.cs    Line: 27

Stack Trace:

[NullReferenceException: Object reference not set to an instance of an object.]
App.Controllers.ProfileController.NewListing() in c:\...\Controllers\ProfileController.cs:27
lambda_method(Closure , ControllerBase , Object[] ) +101
System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +59
... some lines skipped...
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +932
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +188


Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.34212

To fix this you need to initialise the collection first:

[HttpPost]
public ActionResult NewListing(ListingModel model) {
    var newListing = new ListingDBObject {
        Price = model.Price,
        Title = model.Title,
        ContactNumber = model.ContactNumber
    }

    newUser.Photos = new List<PhotoDBObject>(); // Initialise the collection first so it's not null
    foreach (var photo in model.Photos) {
        newUser.Photos.Add(new PhotoDBObject { // Add objects to the collection
            BinaryData = photo.Data;
        });
    }

    //...here goes code that saves new listing to the database
}

But Wait, There’s More!

I hope this article helped you to solve your problem and saved you a bit of time and frustration!

Don’t miss my next post - subscribe to my mailing list to get handy tips and solutions for your ASP.NET MVC problems. I never spam, period.


comments powered by Disqus