PDA

Click to See Complete Forum and Search --> : VS 2010 [RESOLVED] Object reference not set to an instance of the object


Nightwalker83
Jun 8th, 2011, 08:09 PM
Hi,

I keep receiving "Object reference not set to an instance of the object" when trying to run a form. This is the code I am using:


<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MvcMusicStore.Models.Album>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Edit
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<h2>Edit - <%: Model.Title%></h2>

<% using (Html.BeginForm()) {%>
<%: Html.ValidationSummary(true) %>

<fieldset>
<legend>Edit Album</legend>
<%Html.EditorForModel(); %>
<div class="editor-label">
<%: Html.LabelFor(model => model.AlbumId) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.AlbumId) %>
<%: Html.ValidationMessageFor(model => model.AlbumId) %>
</div>

<div class="editor-label">
<%: Html.LabelFor(model => model.GenreId) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.GenreId) %>
<%: Html.ValidationMessageFor(model => model.GenreId) %>
</div>

<div class="editor-label">
<%: Html.LabelFor(model => model.ArtistId) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.ArtistId) %>
<%: Html.ValidationMessageFor(model => model.ArtistId) %>
</div>

<div class="editor-label">
<%: Html.LabelFor(model => model.Title) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Title) %>
<%: Html.ValidationMessageFor(model => model.Title) %>
</div>

<div class="editor-label">
<%: Html.LabelFor(model => model.Price) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Price, String.Format("{0:F}", Model.Price)) %>
<%: Html.ValidationMessageFor(model => model.Price) %>
</div>

<div class="editor-label">
<%: Html.LabelFor(model => model.AlbumArtUrl) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.AlbumArtUrl) %>
<%: Html.ValidationMessageFor(model => model.AlbumArtUrl) %>
</div>

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

<% } %>

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

</asp:Content>


It is complaining about model some reason and I can't figure out why.

The first error occurs on this line:


<h2>Edit - <%: Model.Title%></h2>


However if I remove it the next error occurs on this line and so on:


<%: Html.TextBoxFor(model => model.Price, String.Format("{0:F}", Model.Price)) %>


Have I missed a namespace somewhere?

Thanks,


Nightwalker

jmcilhinney
Jun 8th, 2011, 10:55 PM
If you'd missed a namespace then it wouldn't compile. All that means is that your Model is null. Have a look at where you display the view, i.e. where you call View or the like in a controller action. You'll find that you aren't pass an object at that point. The object you pass when you call View is the Model for the view.

Nightwalker83
Jun 16th, 2011, 09:47 PM
Well, putting the cursor over the modal variable it says it is set to MvcMusicStore.Models.Album.

jmcilhinney
Jun 16th, 2011, 10:08 PM
Well, putting the cursor over the modal variable it says it is set to MvcMusicStore.Models.Album.

That would be it's type, but that doesn't mean that you have passed an instance of that type when creating the view. Can you show us the action where you create that view?

Nightwalker83
Jun 16th, 2011, 11:03 PM
I create the edit view by right-clicking "Edit" then add view this is the code I am creating it from:


// GET: /StoreManager/Edit/5

public ActionResult Edit(int id)
{
var album = StoreDB.Albums.SingleOrDefault(a => a.AlbumId == id);

return View(album);
}

//
// POST: /StoreManager/Edit/5

[HttpPost]
public ActionResult Edit(int id, FormCollection collection)
{
try
{
// TODO: Add update logic here

return RedirectToAction("Index");
}
catch
{
return View();
}
}

jmcilhinney
Jun 16th, 2011, 11:21 PM
Have you confirmed that 'album' is not null when you call View?

Nightwalker83
Jun 16th, 2011, 11:33 PM
Yes, the only part that doesn't seem to be working is this line:


<%: Html.TextBoxFor(model => model.Price, String.Format("{0:F}", Model.Price)) %>

jmcilhinney
Jun 16th, 2011, 11:48 PM
If you click on 'Model.Price' and hit F9 to add a breakpoint, then run the app, what is the value of Model.Price when the breakpoint is hit?

Nightwalker83
Jun 18th, 2011, 01:06 AM
Model.Price equals null although, I am not sure where I set model and Model in the first place.

jmcilhinney
Jun 18th, 2011, 01:10 AM
You're saying that Model.Price is null. What type is that Price property? I would have thought 'decimal' which can't be null, although maybe it's 'decimal?'. Assuming that Model.Price is null, what's the value of Model?

Nightwalker83
Jun 18th, 2011, 02:16 AM
I can't remember setting either model or Model in a generic sense.

Under the column listing it has: Price numeric then in the value/property it has Price/Decimal.

jmcilhinney
Jun 18th, 2011, 03:36 AM
I'm not asking you about the database. I'm asking you about the view. In the view, the Model property is type MvcMusicStore.Models.Album which I know because the @Page directive says so:Inherits="System.Web.Mvc.ViewPage<MvcMusicStore.Models.Album>"That type apparently has a Price property, which I would expect to by type 'decimal'. Is it indeed that type? If so then it can't possibly be null. What value does Model.Price have and, if it doesn't have a value, what value does Model have?

As I said previously, you provide the model for the view when you call the View method in your action. The argument that you pass to the View method is the value of the Model property in the view.

The 'model' that you're talking about isn't something you set. It's a range variable for a lambda expression. The first argument passed to TextBoxFor is a Expression. You could as easily use:x => x.PriceYou simply telling MVC to create a TextBox for the Price property of the model of the view. 'model' is used for the range variable because it makes sense, but it could be called anything.

You're getting a NullReferenceException. When that happens, the first step is always to determine what reference is null. That's what we're trying to do here. The most likely candidate is Model. If Model is null then that means that you aren't passing an object to View when you call it.

Nightwalker83
Jun 18th, 2011, 06:09 PM
Well, the fact that it works for the other fields on the form suggests that I have setup the inherits part correctly. I think it has to do with the fact that Model.Price uses an uppercase "M" instead of a lowercase "m" like the rest of the code above.

I will have to email my lecturer and ask for advice and see if he can figure out what I am doing wrong.

jmcilhinney
Jun 19th, 2011, 04:19 AM
Not having used it for a while, I had a look at the documentation for the TextBoxFor method and, basically, you're using it wrong. You are trying to pass the value to the method but you aren't supposed to. You specify the property of the Model to use in the first parameter and that is used to get the value. Any formatting should be handled by data annotations on the property. If you want to pass a formatted value directly then you should be calling the TextBox method rather than the TextBoxFor method. I suggest that you read the documentation for both.

gep13
Jun 23rd, 2011, 12:59 AM
Yes, the only part that doesn't seem to be working is this line:


<%: Html.TextBoxFor(model => model.Price, String.Format("{0:F}", Model.Price)) %>


I realise that I am joining this thread late, but just noticed something, so I thought I would mention it...

Is the above a copy and paste from Visual Studio? If so, did you mean to have both model and Model? Remember C# is case sensitive.

Gary

jmcilhinney
Jun 23rd, 2011, 01:13 AM
I realise that I am joining this thread late, but just noticed something, so I thought I would mention it...

Is the above a copy and paste from Visual Studio? If so, did you mean to have both model and Model? Remember C# is case sensitive.

Gary

'Model' is a property of the view. 'model' is the lambda expression parameter.

gep13
Jun 23rd, 2011, 01:20 AM
Ah, of source, sorry my bad! Should have read the thread properly :)

Gary

Nightwalker83
Jun 23rd, 2011, 01:21 AM
I realise that I am joining this thread late, but just noticed something, so I thought I would mention it...

Is the above a copy and paste from Visual Studio? If so, did you mean to have both model and Model? Remember C# is case sensitive.

Gary

That is how it was written in the notes I was given. I will check with my lecturer next week to make sure.

jmcilhinney
Jun 23rd, 2011, 01:28 AM
I've explained what the issue is. You are hybridising the TextBox and TextBoxFor methods and not calling either properly. If you want to call TextBoxFor then you don't specify a value. You specify an expression that describes the property of the view's Model you want to create a TextBox for and it does the rest. If you want to format the value then you have to use DataAnnotations on the model class itself. If you want to specify a value then you call TextBox rather than TextBoxFor.

Nightwalker83
Jun 23rd, 2011, 01:54 AM
Putting:


<div class="editor-field">
<%: Html.TextBoxFor(model => model.Price) %>
<%: Html.ValidationMessageFor(model => model.Price) %>
</div>


Shows the form without errors! Although, the screenshot I was given has data in the fields which, probably lead to my confusing in the first place.

jmcilhinney
Jun 23rd, 2011, 02:06 AM
The issue there is that the value will be displayed without currency formatting. If you want to use TextBoxFor and still get currency formatting then you would have to apply a DataTypeAttribute with a DataType of Currency to the Price property of the Album class.

Nightwalker83
Jun 28th, 2011, 02:21 AM
I have finally finished typing up all the code I just need to fix up a couple of mistakes on Thursday so UI an get it working.

Nightwalker83
Jul 1st, 2011, 03:32 AM
Well, I have put the original code back in to the project and it works although, I have no idea why.