2

Ok, so this problem seems incredibly weird to me. I have a view that is used for both editing and creating new articles. Editing existing articles works perfectly, however creating new ones gives me a null reference exception ("Object reference not set to an instance of an object").

Here's my code:

//Return Edit/New partial view. New if Id < 0 (will be -1)
public ActionResult Edit(int Id)
{
    Models.Article a;
    if (Id > 0)
    {
        Models.Entities db = new Models.Entities();
        a = db.Article.FirstOrDefault(dba => dba.Id == Id);
    }
    else
    {
        a = new Models.Article();
        a.Id = -1;
        a.DateProperty = DateTime.Now;    //Repeat for each date property
        a.Property = "";    //Repeat for every string property
    }
    return PartialView("~/Views/Article/Edit.cshtml", a);
}

I then return a view that contains the following (and more along the same lines):

<label for="txtTitle">Title</label>
<input type="text" id="txtTitle" data-originalvalue="@Model.Title" value="@Model.Title" />
<span class="actionButton actionUndo revert" title="Undo Changes">Revert</span>

<label for="txtPublishDate">Publish Date</label>
<input type="text" id="txtPublishDate" class="datePicker" data-originalvalue="@Model.PublishDate.ToShortDateString()" value="@Model.PublishDate.ToShortDateString()" />
<span class="actionButton actionUndo revert" title="Undo Changes">Revert</span>

For some reason every time this Article/Edit?Id=-1 is called the page loads up and I get the afore mentioned error. The code that's highlighted is in the data-originalvalue attribute (a custom HTML5 data field).

If I REMOVE those custom data fields, I get the same error, but [No relevant source lines].

I am very confused as to why this happens.

The models themselves are generated from the database using ADO.Net and the project uses MVC 4 and .Net 4.5.

tereško
  • 58,060
  • 25
  • 98
  • 150
Maverick
  • 4,449
  • 4
  • 36
  • 46
  • No, as explained, I am creating a new object. The ID is -1, that's what I want it to be. When that's passed back into code (via javascript and the "Save" button), then the -1 let's the code behind to add the object to the database. The object DOES exist (it's created and has properties set, which all show up when I hover over `@Model`), but not in the database yet. EDIT: Comment I was responding to just disappeared, probably after reading my OP propperly :). – Maverick May 30 '13 at 00:01
  • Is there a stack trace? – Andrew Savinykh May 30 '13 at 00:13
  • 1
    which data-originalvalue gets highlighted, the one with @Model.PublishDate.ToShortDateString()? If PublishDate is a nullable DateTime and is set to null that might throw the mentioned exception – NeddySpaghetti May 30 '13 at 00:17
  • @ned-stoyanov `@Model.PublishDate.ToShortDateString()` does get highlighted, but it is not nullable and it DOES contain a value. If I remove all the dates, then `@Model.Title` gets highlighted. @zespri I can present one for you, it points only to the line I mentioned though and the only description is in my OP. – Maverick May 30 '13 at 00:30
  • Almost all cases of `NullReferenceException` are the same. Please see "[What is a NullReferenceException in .NET?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-in-net)" for some hints. – John Saunders May 30 '13 at 01:02
  • @JohnSaunders if you'd bothered to read the OP and comments correctly, you'd see that no part of anything that I've called is actually Null, that's why this is confusing me. All variables that are accessed **are** assigned a value that they pass into the View, and according to the .Net debugging tools those properties are still present in the View itself. – Maverick May 30 '13 at 01:25
  • Are those values strings? What is the value it is passing into Model.Title? – RyanJMcGowan May 30 '13 at 01:31
  • The only way to get a `NullReferenceException` is to attempt to dereference a null. Period. – John Saunders May 30 '13 at 01:43
  • @RyanJMcGowan The values are strings, dates and Guids. However if I use only `@Model.Title` (which is set to `""`) I get the same error. @JohnSaunders Then kindly explain how it's possible for my code (which declares an object and assigns it's properties a value) references a null? When I hover over the code in debug the values are not null, they aren't null if I insert a break-point and check the object before passing it to the view and when I use the same code but with the workaround below, everything works perfectly :). – Maverick May 30 '13 at 01:50
  • I don't need to explain gravity to you in order for you to be assured that it works quite universally. The only other way to get a `NullReferenceException` is if some stupid piece of code deliberately throws one, like `throw new NullReferenceException("Object reference not set to an instance of an object");` – John Saunders May 30 '13 at 02:50
  • @JohnSaunders If I were a scientist I WOULD demand gravity be explained to me. However I'm a .Net developer, so I demand explanation for different things. There are no nulls that are referenced in my view, as evidenced by my answer below which uses the EXACT SAME DATA but doesn't have any errors. If you aren't going to be helpful, kindly refrain from commenting without even bothering to read the OP. – Maverick May 30 '13 at 22:58

1 Answers1

0

I think I have the answer. I think this might be an issue with ADO.Net and MVC not liking to play together in this particular way (although if somebody has a better solution PLEASE post it here and I'll accept it as the answer).

I was able to implement the following workaround:

I created a container class called ArticleContainer and an almost-identical class to Article called BlankArticle. It has all the properties the Article object has in the database (note that this is different to the properties assigned to the object in ADO.Net, which I will explain a bit further down the page).

Article container is just the following:

public class ArticleContainer
{
    public ArticleContainer()
    {
        //
    }

    public Article ExistingArticle { get; set; }
    public BlankArticle NewArticle { get; set; }
}

I then create a BlankArticle object (with basically the same properties as Article) and put that in an ArticleContainer object if it's new (eg: Id < 0), or put an Article object (the type generated by ADO.Net) if it's already in the database.

The view then creates variables for each field and assigns them from ExistingArticle if NewArticle is null, or vice-versa.

The reason I needed to do this, is because (as anybody who's tried to return ADO.Net objects as JSON will know) ADO.Net objects that have relationships with other objects have those objects included as PART of the original object.

eg: An Article may have a many-to-one relationship with a View which means that in the View table you'll probably have an ArticleID field that points to a particular article. In the ADO.Net model that View object will have an Article object as a property, whilst an Article object will have a List<View> property (containing obviously a list of views).

Objects that reference other objects in the database, apparently cannot be passed into an MVC View without actually being in the database (even though a new object doesn't ACTUALLY reference anything else in the database, it POTENTIALLY does). The above fix isn't what I'd call elegant, but it is easy and effective, so it's what I'll stick with in future if nobody else has any better ideas.

Maverick
  • 4,449
  • 4
  • 36
  • 46
  • In case it wasn't clear already, btw. The `data-whatever` html attributes don't effect this at all, although I'm not sure why only that code got highlighted in debugging, removing such fields did not actually solve the issue :). – Maverick May 31 '13 at 00:41