Codebehind Files in ASP.NET MVC are Evil

imageWith the current versions of ASP.NET MVC (Preview 5) that have shipped, the default MVC template sites all include codebehind files for the ASP.NET views. For example, here’s a screenshot of what a new project looks like the one at right. Further, adding a new ASP.NET MVC View Page will also include a .aspx.cs and a .aspx.designer.cs file by default.

The question is, why is that codebehind file there, and what are the consequences of having it there by default? If you watch a few screencasts and blog tutorials from Rob, Phil, ScottGu, ScottHa, et al, it’s pretty rare that you’ll find anybody actually putting any real code into the codebehind files for the views. In fact, I’m hoping that in addition to negating the need for codebehind files (there is one – wait for it), Microsoft can also take the next available opportunity to use a different file extension for views to make it incredibly, abundantly clear that they are not to be used like traditional ASP.NET web forms.

Why Are They There?

Today, codebehind files are useful if you want to have a strongly typed View<T>. The easiest way to achieve this is to edit the codebehind file and change:

to

and voila! Now you can reference Customer in a strongly typed fashion from your View’s ASPX file, off of ViewData.Model. Apart from this, the codebehind file may be a useful place to store some display-only functionality or a property that makes accessing a piece of ViewData simpler. Both of which could also easily be done inside the ASPX page – it’s just a matter of personal preference.

Tomorrow (as in, with some future release, I’m guessing), codebehind files may be important for interacting with custom controls. Today that story just isnt’ fleshed out yet.

Getting a View to work without a codebehind is simple provided you don’t need a strongly typed view:

<%@ Page Inherits=”ViewPage” %>

One could still achieve strongly typed views, if they were important, by using the generic backtick notation like this (if VS supported it, which I’m not able to get working so I’m assuming it does not today):

Why are Codebehind Files in Views Evil?

The problem with having a codebehind file for a View comes down to temptation and habit. If it’s there, anybody who’s been using “classic ASP.NET” for the last 8 years or so is accustomed to putting all kinds of things into the ASP.NET codebehind files. From click handlers to Page_Load to event wireups to changing display settings based on the value of a data item – most web forms apps have a ton of logic in their codebehind files. And that’s great – but not typically how it should be done with ASP.NET MVC.

With ASP.NET MVC, the View should be dumb. It should be stupidly simple. It should have no logic in it to speak of, not least of all because it’s difficult to test, but also because that’s the Controller’s whole purpose in life. If you need to do any kind of business logic, it should happen in the Controller. Need to format something a particular way if it’s outside of a particular range? Great, do it in the controller and pass the necessary CSS string into the View as ViewData. Then write a test that proves it works. Beautiful.

Having a codebehind file is a temptation. Developers who are new to ASP.NET MVC (and who isn’t – it’s not even a year old and not released yet) but who have a background with web forms (as most will) are going to have to resist a natural inclination to put code into their codebehind files like they always have. This will make the logic in the View more difficult to test and at worst might even involve logic in the codebehind making calls directly to a database or web service and thus completely bypassing the separation of Model from View as well.

And of course while we’re removing the Codebehind files from the default template, we’ll want to remove the .designer.cs/vb files as well!

Fall into the Pit of Success

If having the codebehind file available by default is a temptation to stray from the canonical correct MVC path, then not having it there by default would help most developers do things the right way without thinking about it. That’s what is meant by helping them to fall into a “pit of success” (not sure who came up with that term, but kudos for it). Sure, some might simply add in a codebehind file (this would still be simple to do) or just write a bunch of complex logic within the ASPX file, but many more would do the right thing and place this logic in their Controller. New developers joining their first ASP.NET MVC project would immediately realize that Views were not the same as Web Forms because they lack the codebehind files typical of web forms. And the 95% of Views that don’t need a codebehind file for anything would have half as many files cluttering their solutions, without the need for manual deletion of the .aspx.cx / .aspx.vb files.

Some folks really want to have codebehind files included. I think they’re a small minority, and if/when codebehind files are necessary for a View, it will still be simple to Right-Click->Add File to get one. But in the default case, when a new View is added to an ASP.NET MVC project (or when a new project is created from the default template), it would only include the ASPX file(s) (and perhaps in a later rev of Visual Studio/ASP.NET, an ASVX file), and no codebehind or designer files.

  • Chris Sutton

    Steven,

    I hope to see the default ASP.NET MVC templates get rid of the code behind as well. They don’t serve a good purpose at this point.

    Chris

  • evodanh

    I agree with: "Codebehind Files in ASP.NET MVC are Evil" 😀

    MVC should be: "fat model, thin controller, stupid view"

  • Matt

    I never did ASP.NET before MVC, and came from a Rails background. One thing I *do* like about having a code behind, is I can hide view logic in it, and not clutter the markup with large conditional checks that have to check for null, empty, etc. values. I can encapsulate a full conditional check into a single property into the code behind – it’s still view logic, because the view is trying to figure out how to handle the data passed by the model, but it keeps my markup/code combinations cleaner.

  • Luke

    I also never did ASP.NET before MVC, so probably I’m unaware that such thing can be made: If you want to your page to be rendered as XML, how can you simply put it into *.aspx file? I do it in the codebehind like:

    protected void Page_Load(object sender, EventArgs e)

    {

    Response.ContentType = "application/xml";

    }

    ASP.NET MVC still lacks many features (such as passing data to Master Pages *easily*) and documentation. It is a pity :( However, I’m looking forward to it.

    PS. My homepage is written entirely in ASP.NET MVC (unfortunately Polish only :()

  • Keith

    Why doesn’t the "Add Item" dialog ask if you want a codebehind file just like ASP.NET 2 does? Any code can easily be put in the view file. It should be view related and I hate opening 2 files just to deal with one view.

    +1 Code behind files are evil.

  • Rob Conery

    You certainly don’t want to put logic back there. The reason they are still included is that, by default, ASP.NET MVC uses the WebFormsViewEngine. Quite simply put, these "pages" are thought of as "classes" and so you have the class file artifact.

    It’s actually helpful (for people like me) who like to work with typed data and who like compile-time checking. In addition can create properties for partials – which is a nice type-safe way of working with data and minimal code.

    For example, I have a partial in the Storefront for displaying Product information. On that partial I have an add to cart button which I only want to show conditionally. This is very specific to this partial, so I created a property for ShowAddToCartButton.

    Anyway – I wouldn’t say code behind is "Evil", but yes, it’s confusing to folks who come from a webforms world :).

  • Brad Wilson

    @Luke, like this in the .aspx file:

    <% Response.ContentType = "application/xml"; %>

  • LaptopHeaven

    @brad_wilson

    Won’t doing things like that start us down the path of spaghetti code, like lots of classic asp projects ended up with?

    ASP.NET MVC != Classic ASP, but a lot of the examples look just like classic ASP.

  • LaptopHeaven

    @brad_wilson

    Won’t doing things like that start us down the path of spaghetti code, like lots of classic asp projects ended up with?

    ASP.NET MVC != Classic ASP, but a lot of the examples look just like classic ASP.

  • Steve Smith

    @laptopheaven,

    Not if all you’re doing is View stuff. If you start putting in lots of other logic, then yes. But just because you have some logic in your ASPX doesn’t make it spaghetti code. That’s just a (very understandable) gut reaction based on all the pain we ASP developers endured, but in my opinion it *is* possible to have <%…%> code in a ViewPage’s ASPX file without it automatically turning into pasta.

  • Andrei Rinea

    I propose the .asvx extension for .aspx files with no code-behind files designed as MVC views 😀

  • Luis Abreu

    My thoughts on this topic are here: msmvps.com/…/codebehind-file

  • foobar

    What’s all this bullsh*t about banning codebehind files? If you don’t want to use C# code in your codebehind, then don’t. Don’t demand Microsoft ban codebehind in the next/final release.

    Grow up, assume responsibility for your own life, or for the way you develop in MVC, dammit.

  • foobar

    Fine, what you’re saying is no .cs or .designer.cs files by default.

    What prevents you from modifying your project template files so that the afore-said files may not be generated? I’ve customized almost every VS2k8 project/item template extremely.

  • Mike

    While you’re at it, why not remove the knives from your kitchen? They could be used to kill someone.

  • ssmith

    @mike – poor analogy; knives in the kitchen are useful to me. These extra files are not. A better one might be "why not remove all the crap that comes preinstalled on your new PC – you might not want some of that stuff, either". To which I would answer, "Hell yeah, remove all that crap." (http://www.pcdecrapifier.com/)

    I’m talking about decluttering, not overprotecting.

  • Dharminder

    How to add the Designer file to an aspx file

  • Dan F

    According to Brad Abrams, it was Rico Mariani who coined the phrase "pit of success" – http://blogs.msdn.com/brada/archive/2003/10/02/50420.aspx. I first read about if via Scott Hanselman. ‘Tis a great term.

    I’d be happier without the codebehind files myself, but I know a few colleagues would freak out royally.

    According to Tim Barcz you can use that funky backtick notation, but it appears you need some extra square brackets – devlicio.us/…/strongly-typed-

  • TimothyP

    I have one situation where I (think I) need to put code in the codebehind. I’m streaming a fiel from another datasource to the client so in classic ASP.NET I’d have to

    Response.ClearContent();

    Response.ClearHeaders();

    Response.ContentType = "…..";

    Response.AppendHeader("Content-Disposition", …

    This is not something I could do in the controller right?

    (Although I haven’t figured out how to make this kind of download page with MVC yet)

    Just saying there are situations where

    code behind might be needed.

  • Timothy

    It would seem having a custom ActionResult class is the way to do it… so you’re right… no need to stuff code in the codebehind :-)

  • Marcelo L

    @foobar: Yes ! I’m not the only one who’s annoyed that in all these years, VS hasn’t shipped with better, more robust templates "out of the box".

  • Andrey Shchekin

    One could still achieve strongly typed views, if they were important, by using the generic backtick notation like this (if VS supported it, which I’m not able to get working so I’m assuming it does not today):

    <%@ Page Inherits="ViewPage1[Customer]" %>

    That is _the_ reason for me. It is possible, by the way, if you use the full generic argument name:

    <%@ Page Inherits="ViewPage1[X.Y.Customer, X.Y]" %>

    but it is much less maintanable.

    I do not really see areason to use untyped ViewPages, and the current syntax for typed ones is too complicated without code-behind.

  • Hassan

    I agree with Matt. I also prefer to put the view logic at code behind not cluttering the markup.It makes the aspx page less readable when you put large conditional checks that have to check for null, empty, etc. values as matt said. It keeps the code/markup cleaner and more readable. Most importantly You CAN NOT resist someone putting bussiness logic on the view only by removing code behind files. the guy would then start writing at aspx page then. a design pattern is a thing to be maintain by the developer.

  • FSI

    And if i need to use some server control like, reportViewer, should i do it in a aspx MVC file or a conventional aspx file with de codebehind??

  • ASP.NET MVC – Coder dismay « Payed Coder

    Pingback from ASP.NET MVC – Coder dismay « Payed Coder

  • SC

    Microsoft has stated all along that V1 of MVC is a "code-focused" released. Future versions may add things such as MVC controls – in those scenarios, you will *need* the code behind files (whether you realize it or not).

    The codebehind files will lead to much cleaner designs than if Microsoft flat out copied rails (where’s the benefit if they did that? Everyone would just run rails!)

    I don’t want code in my markup. It makes more sense to have 100% view code OUT of the markup and into a codebehind file.

    ASP and PHP quickly turn into pages and pages and unmanagable spaghetti code. Lets not go back to the dark ages, just because some close-minded developers demand it? You’re throwing out the baby with the bath water.

    Markup != Class

    MVC was designed to hook controller classes to view classes, not controller classes to view markup.

    You make the argument that "views should be dumb", but yet every example of a view I’ve seen contains code – things like looping, or code for rendering markup. How is putting that *exact same* logic in a code behind file any worse? It’s not, and in fact, it’s much better since it’s a proper separation of concerns.

    You’re arguing:

    Controller -> View Markup with Spaghetti Code

    I’m arguing:

    Controller -> View Code -> View Markup

    A much cleaner separation, and easier to manage. Think outside the box, and stop demanding things because "that’s the way it’s done in Rails/insert existing framework here"

    Evil this, Evil that, blah blah blah blah. Stop sensationalizing and start thinking like an architect.

  • ssmith

    SC – Read this part in the original post: "if/when codebehind files are necessary for a View, it will still be simple to Right-Click->Add File to get one."

    I’m arguing add it when you need it. I’m *not* arguing to put code in the ASPX view file. Period. So don’t try to put words in my mouth.

    I agree they have their place. When you need one, add it. But since many views will not need it, there’s no point in adding it.

    And yes, the whole "evil" thing is a gimmick to get more people to take notice. Sorry, but it works.

    Thanks for your thoughts. I do agree with you (and Bertrand Le Roy) that future versions of MVC, with a better control story, will need codebehind files. That’s why I think they should be simple to add as needed. Otherwise, I’m going to follow YAGNI and Simple Design and suggest we omit that which is not necessary today.

  • Die Code-Behind DIE!!!

    As mentioned in previous episodes, my team is standardizing on the ASP.NET MVC Framework for web development. …

  • Die Code-Behind DIE!!!

    As mentioned in previous episodes, my team is standardizing on the ASP.NET MVC Framework for web development

  • ssmith

    As it happens, the ASP.NET MVC team has agreed that codebehind files will not be created for views by default (if needed, they can still be added), according to ScottGu’s latest post.

    weblogs.asp.net/…/asp-net-mvc-des

  • Maxwell Pryce

    I read all your comments and I agree, now I will pass my file with code in-line to my web designers (I hope they do not mess with the code). MVC is a good thing but I believe view logic goes in the code behind page and developers who place it in their pages generally do not think of multiple people on the same project who are NOT programmers. People who sand box themselves into thinking pure MCV do not understand the concept of progression. I think Microsoft is right in leaving the code behind pages there and I think the pattern deigners should come up with a new abbreviation i.e. MCVLV Model, Code, View Layer, View

  • Andy Bruce

    I have to say that after reading all these entries I am chilled. Although Scott Gu blithely states that code-behind *can* be created, the intent clearly is to follow a much purer MVC implementation. As a poster put it, fat model, thin controller, stupid views.

    Let’s look at Java andd EJB, shall we? Well, after much work in SAP NetWeaver designer (which is just about as pure MVC as I’ve seen and extends EJB to its logical conclusions) I must say I find MVC to be (almost) pure evil. Yes, Occam’s razor suggests that MVC is indeed useful as it has been used for a very long time, and practical as it is being used in practice by too many software systems to name. That does not change its fundamentally evil nature.

    Basically, the first axiom of system administration is to deny whatever is not explicitly allowed. However, the inverse is (or should) be true for software development. MVC goes out of its way to apply a restrictive sysadmin view to software dev. In fact–in SAP’s implementation of MVC the view itself cannot even access its own controls except in one overload (wdDoModify) and then very indirectly. Because you should be binding your controls to data in the view controller which itself binds to data in the model. Modifications to individual controls (enabled, presentation, etc.) should be controlled by data binding states from your context. Otherwise the Wrong Thing may result from us non-purist programming clods.

    Wow! Let’s just dump OO while we’re at it, shall we? After all, data tightly-coupled with functions violates the separation model of MVC. Which, ultimately, leads to much duplicated code, lots of "magic" generated code, and a much slower software dev process.

    This applies to C# especially in light of a great O’Reilly book on keeping Java code thin and easy-to-manipulate. The point of the book’s author is that C#’s strength is its relatively lightweight and open architecture compared to EJB and MVC. And with this insidious evolution of MVC into my beloved C# domain, we’re moving even further into the dreary mid-90s world of M$’s DocView monstrosities. So I can’t agree that taking away code-behind files cuz "someone might not use it the way *I* and the cognoscenti feel is Korrect" is in any way a good thing. As a programmer, I believe that software is made to do my bidding in the way that I deem necessary.

    However, the fact that C# is moving so heavily to MVC is a good sign to me that a new lighter-weight technology must be waiting in the wings to provide relief from the coming heavy-handed and obstructionist Web development paradigm that MVC truly represents. Unfortunately, it looks like I’ll have to suffer through some horrible projects in the meantime. Cheers!

  • ssmith

    @Andy,

    Thanks for your comment! I don’t personally have any experience with SAP NetWeaver or current EJB implementations of MVC. However, I have been running several web apps on ASP.NET MVC previews/betas for the last year and have found the results to be very positive in terms of ease of use and productivity over time. Web Forms apps, in my experience, tend to (not always, but *tend*) have very high productivity in the short term but over time the tight coupling adds sufficient technical debt that progress slows. ASP.NET MVC, done properly, allows for better code (e.g. follows best practices in the OO world like SOLID, DRY, etc.) that can remain malleable over a longer period, resulting in lower costs/greater productivity over the life of a project.

    If you don’t like MVC, you don’t need to use it. Web Forms is going to be around for a very long time. And if you’re looking for something more lightweight, I would think Ruby would be a good one to check out, if you haven’t already.

  • Weekly Web Nuggets #30

    General Some IoC Container Guidelines : Jimmy Bogard presents some good guidelines for working with your IoC container of choice. Lambdas &ndash; Know Your Closures : Jason Olson exposes a tricky behavior of lambdas that can bite even folks that consider

  • Mario

    Have no choice now, time to make new habits 😉

  • ASP .NET MVC, codebehind, kod spaghetti

    Pingback from ASP .NET MVC, codebehind, kod spaghetti

  • Put Your Pages and Views on Lockdown

    Put Your Pages and Views on Lockdown

  • PHPlist Web Host

    Hey,That’s very cool thanks for the info and thanks for the sharing your link

  • Josh

    I find this very ironic.. all of you are discussing how you want to get rid of the .cs and designer pages that automatically get created with the views.. but I actually went searching the web because that exact thing is happening to me and I’m trying to figure out how to get it back to normal. Why isn’t my view creating a .cs and designer page anymore!?

  • ASM

    Yes, Code behind works. What if I really need lots of code. should I go look for it in the model every time I want to change or debug?

    It makes more sense to let each view associated with its own code!!

    Why would we return back to old procedural coding style?

    each view will be independent with its markup and still have separated code – if needed – to do the biz logic.

    I’m sorry folks but I can not see why it’s a good idea to put code stuff in the markup!!

  • ryan

    is a good idea

  • ssmith

    @Josh,

    The view should be passive. All it is is view (markup) and data (placeholders). If there is more logic in it than looping through a collection of placeholders, that logic belongs elsewhere.

  • シャネル バッグ 軽量

    my horrible massacre pointing to 26 people today, which includes 20 minor ones relating to the ages of 6 and simply 8 yoa has well re-structured your head of many americans if it comes to more stringent firearm as well as regulations. ones weapon that has been used by Adam Lanza was really a partially auto strike rifle, and also also the segments performed some ammunition. this time, whereas dems facilitate totally new exclude on to many of these guns, the latest weapon use ballot should suggest that a lot of people today in america become like a running covering,