I’ve been working with a team of guys on several Asp. Net MVC projects since October of 2009. While that isn’t the greatest amount of time, and I’m still no expert, I thought I’d jot down a few of the practices that we have developed to help make coding a bit smoother. Asp. Net MVC, as with every new technology can be used poorly, and when use poorly you try to identify why that code was bad, how it could have been done better.
First, lets think about what the view should be doing – in a single responsibility sort of way: turn data into html. That right there rules out several options. No retrieving data, no extra data transformations. Just turn some data into html. And frankly, that is complicated enough. So a side goal that I strive for is to create a markup page (the aspx) that is similar to the desired html output. The main reason for that side goal is to make double checking the output that much easier. I want to see a ‘div’ in my markup, and have a reasonable idea where that ‘div’ will show up in the html.
1. Keep as much code out of your views as you can.
Don’t make this rule overly simplistic. Some code belongs in the view. A ‘for’ loop to create a table, a simple ‘if’ block to show administrator functionality, stuff like that. But you shouldn’t be having to specify the DateTime format, or string parsing. That is what the ViewModels should do for you. Rule of thumb, if you see a block where there is more C# than HTML, you probably did it wrong.
I will also extend this rule to JavaScript as well. I’ve talked about the why JavaScript should not be in the views before, so this should not be a shock. JavaScript belong in separate files. Period.
2. Make Views typed.
This is true for all views where you have to pass data from the controller to the view. Make a View Model for the view and pass data via that model. This opens up
a whole host of better patterns for you, like typed HtmlHelpers. As a result, it is VERY rare that I will share a view model between views, or even Controller Actions. I make separate models for GET, POST, and DELETE. I guess my view is, the more the merrier.
3. Make the View Models specific to the needs of the view.
OK, this isn’t actually a View best practice, but it is highly related. If you try to keep the model for the view too generic, you end up with a lot of logic in the view to transpose the data into something useful. The key point is that the data in the model serves the view, so all of the work to get the data into the correct format should be done when putting the data into the model. I will often take this to the point where the model will give html elements in the view their CSS classes. So that means I have more than data from the database in the views.
Side note: when it comes to populating View Models with data specific for the View, AutoMapper rocks! That is all.
4. Custom Html Helpers are wonderful things
It is remarkably simple to create your own Html Helper, and once you get the hang of them they are beautiful. They are wonderful little ways to encapsulate a small amount of logic so you can get it out of the aspx view. Use them to encapsulate small amounts of code you need in various place through the project.
Another little “trick” I will use from time to time to create custom models just for a html helper (passed in via the view’s view model).