User987
User987

Reputation: 3823

Binding anonymous type to View in .NET MVC 5

I have a code that I've written which looks like this:

    ViewBag.Items = user.Items.GroupBy(x => x.ItemId).Select(pr => new
            {
                ItemId = pr.Key,
                ImageURL = pr.Select(x=>x.ImageURL).FirstOrDefault(),
                Title = pr.Select(x=>x.Title).FirstOrDefault(),
                Sales = pr.Select(x=>x.Transactions.Sum(y=>y.QuantitySold))

            }).ToList();

As you can see it's a list of anonymous objects... What I'm trying to do now is to bind these values into my already existing view like this:

     <tbody>
                @if (ViewBag.Items != null)
                {
                    foreach (var item in ViewBag.Items)
                    {
                        <tr>
                            <td><img src="@item.ImageURL" /></td>
                            <td>@item.Title</td>
                            <td>@item.Sales</td>
                        </tr>
                    }
                }
            </tbody>

But I'm getting this error:

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

And for other properties as well...

How can I fix this, but to in same time avoid creating extra class that would make the view strongly types.. Can someone help me out ?

Upvotes: 0

Views: 913

Answers (2)

Syed Mhamudul Hasan
Syed Mhamudul Hasan

Reputation: 1349

just cast it to the target type

<tbody>
            @if (ViewBag.Items != null)
            {
                foreach (var item in (List<Items>)ViewBag.Items)
                {
                    <tr>
                        <td><img src="@item.ImageURL" /></td>
                        <td>@item.Title</td>
                        <td>@item.Sales</td>
                    </tr>
                }
            }
        </tbody>

Upvotes: 0

Ehsan Sajjad
Ehsan Sajjad

Reputation: 62488

It is becuase ViewBag is a dynamic type and using it we lose the comiple time safety and intellisense, what you can do it create a ViewModel and use that :

public class ViewModel
{
   public int ItemId {get;set;}
   ...
   ...
   ...
}

and then project on that viewmodel :

var model = user.Items.GroupBy(x => x.ItemId).Select(pr => new
        ViewModel {
                ItemId = pr.Key,
                ImageURL = pr.Select(x=>x.ImageURL).FirstOrDefault(),
                Title = pr.Select(x=>x.Title).FirstOrDefault(),
                Sales = pr.Select(x=>x.Transactions.Sum(y=>y.QuantitySold))

        }).ToList();

return View(model);

now in your view bind your view to that model like:

@model List<YourNamespace.ViewModels.ViewModel>
@if (@Model!= null)
{
     foreach (var item in @Model)
     {
         <tr>
            <td><img src="@item.ImageURL" /></td>
            <td>@item.Title</td>
            <td>@item.Sales</td>
         </tr>
     }
}

Upvotes: 3

Related Questions