Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC ViewData Null

I am currently creating an e-commerce site using C# ASP.NET MVC and have just come across a problem. On pages such as product pages and search results pages, I have to pass Lists of data from my controller to the ViewPage and that works just fine. However, a null reference exception occurs if the Viewdata equals null. It happens inside the viewpage when it loops through the ViewData and displays products or reviews.

//ProductController.cs

public ActionResult Products_Sub(string category, int page)
{
ViewData["Products"] = database.GetByCategory(category, page);
return View();
}

//ViewPage.cs -- product loop

 <ul> foreach (E_Store.Models.Product product in ViewData["Products"] as  
 List<e_store.models.product>)
 {%> 
 <li>
 <img alt="<%= product.Title%>" src="<%= product.Thumbnail %>" /> 
 <a href="/<%=product.Category %>/<%= product.SubCategory %>/<%= product.ASIN %>/1">
 <%=product.Title%></a>
 </li>
 }%>
 </ul>    

The Null Reference Exception occurs when the following piece of code is reached:

  <ul> foreach (E_Store.Models.Product product in ViewData["Products"] as

What I would like to know is the best way to catch this type of error if it does happen, without resorting to if statements that check to see if it is null.

If anyone knows of a good way of doing this I would really love to know.

like image 861
Simeon Wislang Avatar asked Jan 21 '09 06:01

Simeon Wislang


2 Answers

In your case I would have your database.GetByCategory(category, page) method simply return an empty list rather than null, this way your foreach statement just won't have any data to loop through but you won't get a null exception.

In the case that you're not dealing with a list and the item is null, we use

Html.Encode(ViewData.Eval("Field"))

To get the item's HTML value, it will return "" if the item is null.

like image 55
Odd Avatar answered Sep 27 '22 21:09

Odd


you can always use the null coalescing operator inline like this:

<%= product.Title ?? "" %>

..but you will just end up with tags with empty attributes. prob not what you want.

you will prb need to use ifs somewhere. the problem calls for it. but the question is "where can you put them without making it messy?"

i'm ok wo wrap the whole thing in an if. if you're not maybe try a Html extension method for each item of your loop. pass in the ViewData model object and maybe a bool condition to test for eval. i overload the Html.Encode() to Html.IfEncode(condition, stringIfTrue, stringIfFalse) you would try something similar, but for the whole image and anchor group. else maybe build the group in the code behind for that view and just use a

<% =GetImageAndLinkHtml() %>

..for example.

let me know if you need more info

like image 38
Matt Kocaj Avatar answered Sep 27 '22 23:09

Matt Kocaj