The July issue of MSDN Magazine is available online with my article “Guiding Principles For Your ASP.NET MVC Applications”. Another MVC article in this issue is Justin Etheredge’s “Building Testable ASP.NET MVC Applications”. Justin’s article is a good one as he shows you how to design for testability, and includes specific examples with xUnit.net, moq, and Ninject.
Something we both touched on was the topic of code-behind files.
The conversation between two developers (let’s call them Pushy and Principled), goes like this:
Pushy: Is it OK to use code-behind files with aspx views?
Principled: No.
Pushy: But, I have something that’s really, really specific to this one particular view. That’s OK, right?
Principled: No.
Pushy: Oh, come on! You aren’t being pragmatic here. I don’t want to add a Page_Load, I just need a teeny tiny little instance method. I’ll add a code-behind file and stick it inside. It’s tiny! That’s OK, right?
Principled: No.
Pushy: Really now, what do you expect me to do? Build one of those forsakenly awful HTML helper methods with more overloads than the California power grid in August? Don’t you think it’s better to put the code close to the view that uses it?
Principled: No.
This is one scenario where I’d side with Principled. Sure, the code-behind could be simple. Sure, if you are careful it might even be unit-testable. But, the mere fact that code-behind is possible is a fluke and a byproduct from building on an existing framework. Someone writing an MVC view engine from scratch wouldn’t need to provide such a feature that allows you to put anything resembling intelligence near a view.
All of the problems I’ve seen described where code-behind is a solution could easily be solved with an HTML helper, or by using a more robust presentation model that is passed to the view. Some people worry about a proliferation of HTML helpers, but if you absolutely need a helper scoped to a specific view, you can always put the helper in a different namespace that only that particular view will use.
I know your team is disciplined. I know you wouldn’t do anything wrong. I know you want to be pragmatic and do the simplest thing that works. But, think of the first code-behind file in a project as the first broken window. It’s another degree of freedom where entropy can wiggle into your software and undermine maintainability. It’s making a view smarter, which your principles should suggest is wrong.
Thoughts?
Comments
But, people are lazy. And it's hard to force them into writing html helper instead of putting a logic into the view... Best would be to have the code-behind files checked on build time or commit time and if they're there, invalidate whole commit... I think...
If it's important the code behind should not be used, the developers would/should have put effort into switching this functionality off somehow...
why? if you'd say that you shouldn't be using them most of the time, then i'd really agree but I can't understand the dogmatic attitude torward codebehind files. Everything that can be done in a codebehind file can be done in the aspx view or partial view itself, so it's not a question of having or not having codebehind, right?
and I'm not sure on how the "supper dumb view" supporters put fors in their views...after all, how can you test that for loop?
you mention html helpers...i've written a couple...yes, they're handy, but will you be writing a helper for a simple helper which is only used in one view?
stevesmithblog.com/...
It took a large amount of effort to get the team to remove Codebehinds by default from Views (cutting the number of files in the Views folder down by 2/3 when .cs and .designer.cs files were removed). Yes, it might be nice to be able to say that codebehind files just don't work with views, but that may present future problems (one argument for codebehinds is they may play a part in a resuable component story in future versions of ASP.NET MVC). So, the current v1 behavior of they're not there, but you could add them if you thought you knew what you were doing, is a pretty good story, I think.
msmvps.com/...
Argh! Good catch. How embarrassing. I will now inflict pain on myself using a heavy grammar textbook.
I was puzzled, reading until the end looking for the punchline on NTLM security accounts -- never came.
(btw, thanks again for coming to NoVa CodeCamp last month. It was loads of fun)
There is nothing wrong with putting some of this logic in a code-behind. It's the same class, just in a different file