views:

91

answers:

3

Repository code:

public IQueryable<Bundle> getAllCustomBundlesByCompanyID(int companyID)
{
    return from companyBundle in db.CompanyBundles
           join bundle in db.Bundles on companyBundle.BundleID equals bundle.BundleID
           where companyBundle.CompanyID == companyID && bundle.CompanyID == companyID
           orderby bundle.BundleName ascending
           select bundle;
}

Controller code:

    ViewData["OurCategories"] = bundleRepository.getAllCustomBundlesByCompanyID(CompanyID);

View code:

    <ul class="SmallCats">
       <%if(ViewData["OurCategories"] != null){ %>
            <%List<KODmvc.Models.Bundle> ourCategories = ViewData["OurCategories"] as List<KODmvc.Models.Bundle>; %>
            <%foreach(KODmvc.Models.Bundle b in ourCategories) { %>
            <li><a href="<%=b.BundleID%>">
                <img src="/Content/images/bundleicons/<%=b.BundleIcon %>" />
                <%=b.BundleName %></a>
            </li>
            <%} %>
        <%} else { %>
            There are no custom categories.
        <%} %>

    </ul>

ERROR:

 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 38:                <%if(ViewData["OurCategories"] != null){ %>
Line 39:                     <%List<KODmvc.Models.Bundle> ourCategories = ViewData["OurCategories"] as List<KODmvc.Models.Bundle>; %>
Line 40:                     <%foreach(KODmvc.Models.Bundle b in ourCategories) { %>
Line 41:                     <li><a href="<%=b.BundleID%>">
Line 42:                         <img src="/Content/images/bundleicons/<%=b.BundleIcon %>" />


Source File: e:\Bancroft Archive\PanamaTrunk\Views\Asset\AdminDashboard.aspx    Line: 40 

But I am checking to make sure the ViewData is not null before letting it in, what on earth??

+3  A: 

Well, if the as cast doesn't match the type you supply, then it returns null. Your foreach dereferences ourCategories, which might well be null at this point.

You should use a () cast if you're not going to explicitly test ourCategories for null. Then you'll get a meaningful error if the cast fails.

Craig Stuntz
hmm yeah: Unable to cast object of type 'System.Data.Linq.DataQuery`1[KODmvc.Models.Bundle]' to type 'System.Collections.Generic.List`1[KODmvc.Models.Bundle]'. But I have done that before why won't it work now I wonder? curious... thanks!
shogun
ah you know what I remember what I did last time I used the .ToList() method for IQueryable<>... whoops
shogun
+1  A: 

getAllCustomBundlesByCompanyID will not return a List.

Change this line:

<%List<KODmvc.Models.Bundle> ourCategories = ViewData["OurCategories"] as List<KODmvc.Models.Bundle>; %>

To this:

<% var ourCategories = new List<KODmvc.Models.Bundle>(ViewData["OurCategories"] as IEnumerable<KODmvc.Models.Bundle>); %>

Edit

If you want to keep the lazy evaluation you can simplify the code even more.

<% foreach (var category in (IEnumerable<KODmvc.Models.Bundle>)ViewData["OurCategories"]) %>
ChaosPandion
It is also a good idea to not evaluate to a list until the values are actually needed. In this specific case it wouldn't matter, but in general it is a good idea to keep everything IQueryable as long as possible.
TheHurt
YES worked like a charm, you rock.
shogun
You haven't fixed the problem he asked about, though; the unchecked cast is still there, and will break again if his controller changes.
Craig Stuntz
Not exactly as long as you `as` it to IEnumerable which most collection classes will implement.
ChaosPandion
`ViewData["OurCategories"]` could be an integer for all you know inside the view. Also, you didn't cast it to `IEnumerable`; you cast it to `IEnumerable<KODmvc.Models.Bundle>`, an entirely different, and *far* more restrictive type. Use `as` when you're going to test against null, and `()` otherwise.
Craig Stuntz
I mean you are absolutely correct, but I just cannot imagine him replacing a list of categories with something that is not enumerable.
ChaosPandion
A: 

Your object is an IQueryable<KODmvc.Models.Bundle>, not a List<KODmvc.Models.Bundle>.

Therefore, the expression ViewData["OurCategories"] as List<KODmvc.Models.Bundle> will equal null. If you change it to a regular cast, (List<KODmvc.Models.Bundle>)ViewData["OurCategories"], it will throw an InvalidCastException.

To solve this, you need to either change the controller method to call ToList on the IQueryable so that the model will hold a List<KODmvc.Models.Bundle>, or change the View to cast to IQueryable<KODmvc.Models.Bundle>.

SLaks