1

With the ViewBag, I'm able to set random properties, and access them in a View. However, if I create a list of dynamic objects, I am unable to access the properties of those objects. Is there any way to achieve this?

Here is a basic example:

Controller Code:

List<dynamic> Details = new List<dynamic>();
dynamic detail = new {
    serviceDate = DateTime.Now.ToString("MM/dd/yyyy"),
    Charge = 100.01
};
Details.add(detail);
ViewBag.Details = Details;
return View();

View Code:

@foreach (dynamic detail in ViewBag.Details) {
     <li>
         @String.Format("{0} - {1}", detail.serviceDate, detail.Charge)
     </li>
}

The exception I get is:

'object' does not contain a definition for 'serviceDate'

When debugging the view though, the object clearly has a variable called 'serviceDate'

Brosto
  • 4,445
  • 2
  • 34
  • 51

3 Answers3

2

Instead of create a anonymous object you can create a expando object and then it can be used in view:

dynamic detail = new ExpandoObject();
detail.serviceDate = DateTime.Now.ToString("MM/dd/yyyy");
detail.Charge = 100.01;
Ankur
  • 33,367
  • 2
  • 46
  • 72
0

Thanks for Ankur. I'm facing the same problem and it's solved now.

Create ExpandoObject and add it to the Details List.

Example:

Controller Code:

List<dynamic> Details = new List<dynamic>();
dynamic detail;
detail = new ExpandoObject();
detail.serviceDate = DateTime.Now.ToString("MM/dd/yyyy");
detail.Charge = 100.01;
Details.Add(detail);

detail = new ExpandoObject();
detail.serviceDate = DateTime.Now.ToString("MM/dd/yyyy");
detail.Charge = 50;
Details.Add(detail);

ViewBag.Details = Details;
return View();

View Code:

@foreach (dynamic detail in ViewBag.Details)
{
    <li>
        @String.Format("{0} - {1}", detail.serviceDate, detail.Charge)
    </li>
}

Output:

07-22-2015 - 100.01
07-22-2015 - 50

Another way is to add @model dynamic in the top of View and use return View(Details) in the Controller instead of ViewBag.

stenlytw
  • 938
  • 13
  • 18
0

I don't believe you can use anonymous types like that. I'm pretty sure you can only use them in the scope of the method creating the objects.

You might be able to use reflection to get data from the object, but I wouldn't advise that. If you need to use the object outside the scope of the method, I would create a class for it, like this:

class Detail
{
    public DateTime ServiceDate { get; set; }

    public Decimal Charge { get; set; }
}
James Johnson
  • 45,496
  • 8
  • 73
  • 110
  • even changing it to List it still doesn't work. Besides creating a full model, is there a way to get the results I'm after? When I'm in the view, I'm able to pass data to the controller this way, but I believe that's happening through a query string. – Brosto Oct 17 '11 at 15:43
  • There is no way to fully preserve the object. You can use reflection to get the information from the object, but that's not exactly elegant. – James Johnson Oct 17 '11 at 15:45
  • I think starsky's comment above is what I'm looking for. Thanks for your input though! – Brosto Oct 17 '11 at 15:48
  • If you have any problems with that approach, you should try just creating a class for the object. – James Johnson Oct 17 '11 at 15:52