Can Poyrazoğlu
Can Poyrazoğlu

Reputation: 34780

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?

Upvotes: 7

Views: 28681

Answers (4)

D Stanley
D Stanley

Reputation: 152521

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))

Upvotes: 40

Alekz Varkatzas
Alekz Varkatzas

Reputation: 7

You can do this:

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

Upvotes: -5

Oualid KTATA
Oualid KTATA

Reputation: 1116

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

Upvotes: 1

JuhaKangas
JuhaKangas

Reputation: 883

You need to cast your object since the viewbag is dynamic. For example:

var list = ViewBag.List as List<int>();
list.Count();

Upvotes: 0

Related Questions