Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a 'codebehind' file for an ASP.NET-MVC View in RC1 to be created by default

In RC1 the behavior of the template for creating a view changed.

As explained by Scott Gu's post about the release candidate a newly created aspx view doesn't have a code-behind file by default anymore.

Based on feedback we’ve changed view-templates to not have a code-behind file by default. This change helps reinforce the purpose of views in a MVC application (which are intended to be purely about rendering and to not contain any non-rendering related code), and for most people eliminates unused files in the project.

The RC build now adds C# and VB syntax support for inheriting view templates from base classes that use generics. For example, below we are using this with the Edit.aspx view template – whose “inherits” attribute derives from the ViewPage type:

I really like being able to write view specific code in the codebehind to just output the view - especially if I have logic repeated in several parts of the page where I cant justify creating a partial view.

My actual question: Scott said by default - which implies I can change that behavior, but i cannot seem to see where. Is it possible? Manually creatingn a codebehind file and changing things around is a pain.

This causes an additional problem too :

  • If I refactor the name of my model then the directive in the View isn't updated. This isn't the end of the world, but one distinct advantage of having it fully strongly typed.

Addendum: For those of you wondering WHY I would want a codebehind here are some of the possible reasons. This is a cumulative list of just about everything I've thought of. It goes without saying (well it should) that you mustn't access any data other than that which is already in the model. LINQ would be fine for simple manipulation of model data, but LINQ to SQL would NOT! MVC is for people who should already know this - thats why I love it - made BY smart people FOR smart people.

  • Databinding legacy ASP.NET controls - if an alternative is not available or a temporary solution is needed.
  • View logic that requires recursion to create some kind of nested or hierarchical HTML.
  • View logic that uses temporary variables. I refuse to define local variables in my tag soup! I'd want them as properties on the view class at the very least.
  • Logic that is specific only to one view or model and does not belong to an HtmlHelper. As a side note I don't think an HtmlHelper should know about any 'Model' classes. Its fine if it knows about the classes defined inside a model (such as IEnumerable<Product>, but I dont think for instance you should ever have an HtmlHelper that takes a ProductModel.
  • HtmlHelper methods end up becoming visible from ALL your views when you type Html+dot and i really want to minimize this list as much as possible.
  • What if I want to write code that uses HtmlGenericControl and other classes in that namespace to generate my HTML in an object oriented way (or I have existing code that does that that I want to port).
  • What if I'm planning on using a different view engine in future. I might want to keep some of the logic aside from the tag soup to make it easier to reuse later.
  • What if I want to be able to rename my Model classes and have it automatically refactor my view without having to go to the view.aspx and change the class name.
  • What if I'm coordinating with an HTML designer who I don't trust to not mess up the 'tag soup' and want to write anythin beyond very basic looping in the .aspx.cs file.

I think people are biased against 'code-behind' since it has traditially been interpreted to mean 'event handling code' as opposed to 'the other half of a view's partial class' which is what it is.

Code-behind for views is just fine.

I'm not disagreeing that it clutters up the folder structure a little, but thats what the + icon is for. I just want the ability to create a view with codebehind using 'Add view'.

like image 540
Simon_Weaver Avatar asked Jan 28 '09 21:01

Simon_Weaver


2 Answers

To answer your question directly, I don't think you can change this default. You could try modifying the template (which would be somewhere in %programfiles%\Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplates"), but I don't know for sure.

However, the "MVC-way" for this scenario is probably to create a custom helper, in a separate class.

I recently wrote a web app that used Gravatar (http://www.gravatar.com) to generate profile pictures and I kept writing the same custom <img> tags all over my views, so I created a helper: Html.Gravatar()

Just create a static class "MyHelpers" or "GravatarHelpers" or "FooHelpers" and add static extension methods with signatures like this:

public static string Gravatar(this HtmlHelper htmlHelper, string emailAddress) {
    return htmlHelper.Image(...);
}

or, if you use strongly typed views (ViewPage<T>) and want to take advantage of that you can extend HtmlHelper<T>

public static string Foo<TModel>(this HtmlHelper<TModel> htmlHelper, ...) {
    // Do stuff
    return // Stuff
}

You can easily switch out HtmlHelper for UrlHelper or AjaxHelper. I believe you can also access the ViewData, etc. from a ViewContext property on the helper.

like image 122
Andrew Stanton-Nurse Avatar answered Oct 11 '22 02:10

Andrew Stanton-Nurse


That really doesn't seem like a great idea. Every commentary I've read has said "don't use the code-behind; we wish it wasn't there". And I agree. You could try writing your logic in extension methods (traditionally on HtmlHelper) like here.

like image 28
Marc Gravell Avatar answered Oct 11 '22 03:10

Marc Gravell