Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC ViewBag list of anonymous class throws error on Count() method

I have a serverside code where I'm returning a list of anonymous class from the database:

    public ActionResult DisplayMap()
    {
        ViewBag.Checkins = (from locationUpdate in db.LocationUpdates
                            select new
                            {
                                locationUpdate,
                                locationUpdate.User
                            }).ToList();
        return View();
    }

At the Razor page, I want to get the count of this list:

@if (ViewBag.Checkins.Count() > 0)
{ ... }

However, it throws an error:

An exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred 
in System.Core.dll but was not handled in user code.

Additional information: 'object' does not contain a definition for 'Count'

When I type ViewBag.Checkins in immediate window, I get:

ViewBag.Checkins
{System.Collections.Generic.List<<>f__AnonymousType6<MY_APP.LocationUpdate,MY_APP.User>>}
    [0]: { locationUpdate = {System.Data.Entity.DynamicProxies.LocationUpdate_4532566693B61EF657DDFF4186F1D6802EA1AC8D5267ED245EB95FEDC596E129}, User = {System.Data.Entity.DynamicProxies.User_816C8A417B45FE8609CD1F0076A5E6ECBAB0F309D83D2F8A7119044B1C6060CF} }

The Checkins object is indeed a List, and the data is correct. I've tried Count, Length too (without method call, just as properties) but no luck. What am I doing wrong?

like image 961
Can Poyrazoğlu Avatar asked Apr 29 '14 13:04

Can Poyrazoğlu


2 Answers

ViewBag is dynamic, while Count is an extension method, which isn't supported dynamically (it has to be bound at compile time).

You can either cast to an IEnumerable<dynamic>:

@if (((IEnumerable<dynamic>)ViewBag.Checkins).Count() > 0)

or use the static method directly:

@if (Enumerable.Count(ViewBag.Checkins) > 0)

Or create a strongly-typed model with a Checkins property and avoid ViewBag altogether.

EDIT

Since you're just wanting to check if the count is greater than 0, Any is more appropriate (and may save some processing time depending on the scenario):

@if (Enumerable.Any(ViewBag.Checkins))
like image 63
D Stanley Avatar answered Sep 20 '22 07:09

D Stanley


The viewbag is dynamic which make it an anonymous type generated as internal. It's better that you use view models instead.

and then call the view with its model, do something like this:

public class MyViewModel{
LocationUpdate LocationUpadte{get;set;}
User User{get;set;}
}

public ActionResult DisplayMap()
{
        var model = (from locationUpdate in db.LocationUpdates
                            select new MyViewModel
                            {
                                locationUpdate,
                                locationUpdate.User
                            }).ToList();
        return View(model);
}

then in you razor view

@Model.Count() will return the expected value

like image 29
Oualid KTATA Avatar answered Sep 18 '22 07:09

Oualid KTATA