5

I want to use an ExpandoObject as the viewmodel for a Razor view of type ViewPage<dynamic>. I get an error when I do this

ExpandoObject o = new ExpandoObject();
o.stuff = new { Foo = "bar" };
return View(o);

what can I do to make this work?

kenwarner
  • 28,650
  • 28
  • 130
  • 173

4 Answers4

15

You can do it with the extension method mentioned in this question:

Dynamic Anonymous type in Razor causes RuntimeBinderException

So your controller code would look like:

dynamic o = new ExpandoObject();
o.Stuff = new { Foo = "Bar" }.ToExpando();

return View(o);

And then your view:

@model dynamic

@Model.Stuff.Bar
Community
  • 1
  • 1
gram
  • 2,772
  • 20
  • 24
  • 2
    this ended up working after all. it didn't work the first time I tried it b/c I was actually doing something like `ctx.Foo.Select(x => new { Foo = "bar" }.ToExpandoObject()).SingleOrDefault()` when I should have been doing `ctx.Foo.Select(x => new { Foo = "bar" }).SingleOrDefault().ToExpandoObject()` – kenwarner Jun 24 '11 at 17:44
4

Using the open source Dynamitey (in nuget) you could make a graph of ExpandoObjects with a very clean syntax;

  dynamic Expando = Build<ExpandoObject>.NewObject;

  var o = Expando (
      stuff: Expando(foo:"bar")
  );

  return View(o);
jbtule
  • 31,383
  • 12
  • 95
  • 128
1

I stand corrected, @gram has the right idea. However, this is still one way to modify your concept.

Edit

You have to give .stuff a type since dynamic must know what type of object(s) it's dealing with.

.stuff becomes internal when you set it to an anonymous type, so @model dynamic won't help you here

ExpandoObject o = new ExpandoObject();
o.stuff = MyTypedObject() { Foo = "bar" };
return View(o);

And, of course, the MyTypedObject:

public class MyTypedObject
{
    public string Foo { get; set; }
}
David Fox
  • 10,603
  • 9
  • 50
  • 80
  • yep this is pretty much where I ended up before I had asked on here. If I need to make `MyTypedObject`, might as well ditch the dynamic usage and go back to strongly typed viewmodels :\ – kenwarner Jun 24 '11 at 16:53
  • @qntmfred I think @gram has the right idea. I tested the code and it seems to do the trick. It's definitely closer to specifically answering your question. – David Fox Jun 24 '11 at 17:42
  • yep his approach worked. I commented on his answer as well - I was just doing it slightly wrong the first time I tried it – kenwarner Jun 24 '11 at 17:47
0

Try setting the type as dynamic

dynamic o = new ExpandoObject();
o.stuff = new { Foo = "bar" };
return View(o);

Go through this excellent post on ExpandoObject

Eranga
  • 32,181
  • 5
  • 97
  • 96
  • 1
    While this corrects the compile error, how are you able to access `@Model.stuff.Foo` in the view? `dynamic` objects must know the type of object its dealing with. – David Fox Jun 24 '11 at 14:56