foreach() over List<T> in ViewBag recognizes T as object instead of actual type

1.1k Views Asked by At

I am getting this strange error where Razor would say a property does not exist within an object. I sense I am doing a silly mistake, but I've been battling with this for a while but no luck. Any clues?

Controller method:

List<Conversations> lConversations = usr.conversations.OrderBy(o => o.active).ThenByDescending(o => o.updated_at).ToList().Select(i => new Conversations
{
    Created = i.created_at, Creator = string.Format("{0} {1}", i.user.first_name, i.user.last_name), Name = i.name, Status = (i.active) ? "Active" : "Deactivated", TotalUsers = i.message_recipient.Count(c => c.active)
}).ToList();

ViewBag.conversations = lConversations;

Within the view file, I attempt to foreach through the object and print out the data.

@foreach (var i in ViewBag.conversations)
{
    <tr>
        <td>@i.Name</td>
        <td>@i.TotalUsers</td>
        <td>@i.Creator</td>
        <td>@i.Status</td>
        <td>@i.Created</td>
    </tr>
}

The error message which I am getting is: 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 'Name'

Edit: Conversation Object

public class Conversations
{
    public string Name { get; set; }
    public int TotalUsers { get; set; }
    public string Creator { get; set; }
    public string Status { get; set; }
    public DateTime Created { get; set; }
}
3

There are 3 best solutions below

0
On BEST ANSWER

I found using a ViewBag was the incorrect method for myself, since I was aware of what the data types I was using cause I was setting them - I used a model.

However, as mentioned above in previous comments. Casting the variable to a explicit type also resolved the problem as well.

0
On

ViewBag, as far as I am aware, is not strongly typed - you could try to cast if you know the type of the object. (Presumably you do, since your controller populated it)

You could also try passing a strongly typed object or use a ViewModel.

0
On

An option would be to use ViewData

In your controller

ViewData["Conversations"] = lConversations 

In your view

List<Conversations> lConversations = ViewData["Conversations"] as List<Conversations>;