views:

88

answers:

4

I like the way model binding in django works: you send stuff that you need in a Json-like way:

'param1': val,
'param2': val

In ASP.NET MVC you can't do it primarily because C# is a static language. You can use ViewData but it's ugly and not recommended.

So I had to create dozens of ViewModels for every view: IndexViewModel, AboutViewModel, etc. And today I got an idea: why not just create one Model class and have Visual Studio generate all necessary fields? It's almost like in django.

return View(new Model
            {
                Param1 = "asd",
                Param2 = "sdf"
            });

Param1 & Param2 are not members of the Model class, but Visual Studio will automatically generate them.

Now my question is, is it gonna work? The thing is that there will be a lot of fields in this Model class. And when we pass it to a view, only a small percentage of fields made for that view in particular will be used. Is it gonna be bad performance wise?

Thanks

A: 

Just use dynamic

gandjustas
It's supported only in ASP.NET MVC 3 Preview 1 which is far from being stable.
Alex
You can inherit views from ViewPage<dynamic> and pass ExpandoObject as model.
gandjustas
+1  A: 

There's no reason it shouldn't work.

You can even skip the Model class and create an anonymous type with just the members you need.

return View(new { Amount = 108, Message = "Hello" });

The problem using anonymous types is that you're giving up on auto-completion in the view since you won't be able to type the view according to the model.

samy
When using anonymous types, we have to cast objects using the 'as' keyword. Also I'm not giving up on auto completion, why would it not work?
Alex
indeed, if you have one Model class with all possible members, it would work. I was thinking about using the anonymous type :p
samy
I don't understand the necessity for the cast, though
samy
@samy, here's why: http://stackoverflow.com/questions/223713/can-i-pass-an-anonymous-type-to-my-asp-net-mvc-view/224005#224005
Alex
In fact, there is no need to cast :) If you create a view with the anonymous object above, you can type <%= Model.Amount %> and it will output 108. You won't have auto-completion. But you'll have a lean ViewModel
samy
Yes but basic operations like Model.Amount + 2 and foreach loop will need it :)
Alex
+3  A: 

If you have all these properties on your ViewModel which aren't used (i.e null or whatever) it isn't really going to impact performance. What it will impact however, is your design.

Generally speaking, one model to rule them all as you are proposing is a bit evil and goes against separation of concerns. ViewModel's should be very simple and should be tailored to the view. ViewModel's shouldn't really provide the view with more or less data than what the view needs to render.

Consider this....

You have a generic model with 15 properties on it and you only set a handful of them. Somebody else is designing a view and looks at the model, they may not know which of those properties are sent and under what conditions they are set. They may be attempting to display data that does not exist. This isn't a very clean approach.

I would stick to individual view models and where there is common functionality between views, create an abstraction or base ViewModel form which other views can extend.

Edit: One other thing you could do is use the new MVC 3 (still in preview) syntax for setting ViewData properties directly as if there were properties.

So rather than doing

ViewData["FirstName"] = "Bob";

You can do

ViewModel.FirstName = "Bob";

So this gives you dynamic variables automatically in MVC 3.

Joshua Hayes
Good point. What I want to do, is to imitate django's behavior. The Model.cs class shouldn't even be looked at, because it's completely auto-generated. But I'll think about what you wrote.
Alex
I totally agree with the viewmodel being as simple as possible
samy
Completely auto generated is recipe for disaster. Whilst more convenient initially (because you don't have to code up front) it will be very brittle, harder to debug when issues occur and harder to test. The problem with dynamic is that you don't get compiler time checking and the type of a dynamic variable can change and you might not notice.
Joshua Hayes
Alex, even if you don't look at the model, it's an abstraction that may leak. If each person adds to it without supervision, you may (that's a big may, but it exists) run into performance problems, or worse discrespancies between expected and observed behaviors. Just imagine somebody adding a property to automatically fill two fields (splitting a string to name and nickname, for example). This change could bleed into other parts you're not aware of.
samy
Yeah, I don't want to use dynamics because of loosing type checking.
Alex
If you provide a little more information about your actual domain I may be able to suggest some ideas for structuring your models. In general though, think if maybe there are commonalities amongst your models that you would like to create base models from and have your other models extend these. If this isn't the case, then your data IS different and SHOULD belong in different views. Its best practice to only give a View the data it needs. No more and no less.
Joshua Hayes
+2  A: 

Have a look a Clay the 'malleable' object model being used by the Orchard Project.

http://weblogs.asp.net/bleroy/archive/2010/08/16/clay-malleable-c-dynamic-objects-part-1-why-we-need-it.aspx

http://weblogs.asp.net/bleroy/archive/2010/08/18/clay-malleable-c-dynamic-objects-part-2.aspx

Clicktricity
Thank you for the clay link, i didn't know about it but it's very interesting
samy