- Combining code and markup is ugly. Due to a visual studio bug and our tabbing system that was especially true. Remember that ugly code is hard to read code.
- It is easier to test straight code than Razor's cshtml.
The next page I worked on I decided to go this way. I had a situation where I was rendering a table. For one column sometimes I wanted to render a link and sometimes I wanted to render text. Before I would have put an if in the cshtml, but I tried moving the code into the ViewModel. I instantly ran into the issue of using HtmlHelper. I had no access to this class. I toyed with the idea of creating one, but I didn't have a pointer to the controller which is needed to create an HtmlHelper. I could have passed a pointer to the controller into the ViewModel, but it looked like I was quickly generating an unacceptably hacky solution.
Another smell I quickly generated was that I started using region tags. Now I like the region tag, but people who hate that tag and say that it exists to cover up bad design have a point.
So I decided to go another way. I decided to put view logic where it is supposed to go, the WebViewPage. One nice thing about this is that I can access HtmlHelper easily. Now this leaves me with a lot of objects. I have a Controller, a Handler, a Model, a ViewModel, a View, and now ViewLogic. But since most people believe lots of small, clearly defined objects are better than big ones with potentially multiple functions I think this is reasonable.
Here is the basic process:
- Create a ViewLogic class. The class signature should be public abstract class XXXViewLogic<TModel> : WebViewPage<TModel> where TModel : XXXViewModel
- Remove your @model in the cshtml and replace with @inherits XXXViewLogic<XXXViewModel>
You can now access methods in the ViewLogic class just by calling them in the cshtml. You can keep html markup out of your ViewModel. Your view logic is in a testable class and is nicely isolated from business logic and from your models. You can also easily attach breakpoints to the view logic class which can be handy.
I really like MVC and am fairly neutral on Razor, but I think many decisions made were to put distance between MVC and WebForms. It seems to me that a lot of useful stuff was tossed out because it was too WebFormsy. Having a code behind for view logic fits extremely well into MVC as does ViewState. Ironically, both fit better into MVC than into WebForms, but aren't common patterns in WebForms.
No comments:
Post a Comment