4

(I'm posting and answering this question in one go because it's taken me a good hour to figure this out - and I hope it'll help others)

Update - I've also posted an issue on the Asp.Net MVC Codeplex Issues board in case you're affected by this and you feel like voting for a fix. The code for the MVC tools is not open-sourced so we can't simply submit a pull request for what would be a very simple fix.

We've upgraded a large Web Forms site to include MVC 4 and we intend to run the two strands side by side for the foreseeable future (there's a massive Webforms codebase, so it can't just be converted quickly).

For the MVC side of things we intend to use only Razor for our views. We will also be running MVC code under areas initially, as we already have a complex proprietary routing engine that rewrites urls for the webforms side of things.

Having performed the correct steps in the project file and web.config, we've been able to get it all running nicely, but there's one niggling problem.

Whenever we do 'Add View' for the first time after loading the project, ASPX is always the selected view engine. To avoid confusion we really need that to be Razor by default.

I've looked at How to make razor the default view engine in existing project and I'm upgraded my project to Razor view engine, but VS2010 still auto-generates WebForms; and we do have Razor views in the project - so it can't be as simple as having at least one Razor view in the project.

Community
  • 1
  • 1
Andras Zoltan
  • 41,961
  • 13
  • 104
  • 160

1 Answers1

4

The accepted answer on How to make razor the default view engine in existing project only tells half the story.

As I established in the question - we do have razor views in the project - but it turns out that you need to have a ~/Views folder in the project for this logic to kick in. In our case, we're using areas for all our MVC 4+ code, and so we didn't bother creating a ~/Views folder.

I reflected the Asp.Net MVC VS extension's Add View dialog - in the Microsoft.VisualStudio.Web.Mvc.UserInterface.MvcAddViewDialog.Init method (I've added the comments from my analysis of this code) you find the code that selects the default view engine for when dialog is first shown:

//find the project's Views folder
ProjectItem viewsFolder = MvcProjectUtil.GetViewsFolder(this.Project);
//if not found, or if a view engine is already cached then skip this
if (viewsFolder != null && string.IsNullOrWhiteSpace(viewEngineName))
{
  //has razor views?
  bool flag = false;
  //has webforms views?
  bool flag2 = false;
  //scan all folders and files in the project, looking at all file extensions
  //if .cshtml or .vbhtml are found, then flag==true
  //if .aspx are found, then flag2 == true
  //both can be true when this method returns.
  this.GetViewTypes(viewsFolder.ProjectItems, ref flag, ref flag2);
  //if there's at least one razor view, or if there are no webforms views
  if (flag || !flag2)
  {
    //assign either C# or VB razor view type
    viewEngineName = ((this.Project.Kind == 
      "{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") ? "VBHTML" : "CSHTML");
  }
}
//this'll get bound in the combo on the dialog
this.ViewEngineName = viewEngineName;

So as you can see, the scanning for view types is only conducted on the ~/Views folder - it doesn't bother looking for areas.

All we had to do was to add an empty ~/Views folder (although we did also copy over the Web.Config for this to add the 404 handler) and on the next reload of the project, Razor was auto-selected in the dropdown. This is because, as correctly described in the accepted answer on the aforementioned SO, Razor is used if there razor views are found OR if no webforms views are found in that folder.

Community
  • 1
  • 1
Andras Zoltan
  • 41,961
  • 13
  • 104
  • 160
  • This is superb. I already had a Views folder, but it was not included in the project for similar reasons as you (mine is a class library with the .csproj file manually edited a bit). Once I did "show all files" and included the empty folder, it all worked fine. Thanks! – Tom Chantler Jul 24 '13 at 11:44