Creating a Custom ASP.NET MVC Project Template

asp.net, asp.net mvc 0 comments suggest edit

UPDATE: I have an example Really Empty project template up on GitHub you can look at. I improved on this technique a bit in that one.

When you create a new ASP.NET MVC 3 project, the new project wizard dialog contains several options for different MVC project templates:

There’s a lot of white space in that dialog. To many of you, all that unsullied territory smells like opportunity. When I talk about this dialog, I go to great pains to tell folks that, yes!, you too can extend that dialog and add your own project templates in there.

If you wanted to, you could have your own ASP.NET MVC 3 project template configured exactly the way you want. Hate the default template? Make your own!

The only problem is, I keep telling you that you can extend it, but sadly I never told you how. But that’s about to change!

I don’t expect that a large number of people will want to do this, which is one reason we haven’t spent a large amount of time making it easy (though that may change in the future). But for the few of you impatient masochists who want to add your own custom templates now, this blog post will walk you through the hacking around it takes to make it happen.

Imitation is the sincerest form of productivity

The easiest way to get started is to simply copy and modify an existing project template. For example, I looked in the following directory:

C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ProjectTemplates\CSharp\Web\1033

on my machine and stole *ahem* borrowed the project template named MvcWebApplicationProjectTemplatev3.01.cshtml.zip. Note that the 1033 folder is for English (en-US) templates. For other languages, you may need to look in a different folder.

I then renamed it to MyProjectTemplate.cshtml.zip and extracted the contents into a folder so I could make some modifications to its contents.

MyProjectTemplate.cshtml

When you extract the contents, you’ll want to rename the .vstemplate file to match the name of the template you chose. In my case, I renamed MvcWebApplicationProjectTemplatev3.01.cshtml.vstemplate to MyProjectTemplate.cshtml.vstemplate.

Open up the .vstemplate file in NotePad and make sure to change the TemplateID element value to something unique.

You can change any of the contents of the template folder now, but be very careful to make sure that any additions or deletions of content are reflected in the .vstemplate file. That file is a manifest of all the files within the VSIX package that makes up the project template. Also make sure that the .csproj file reflects those changes as well, to ensure any new files you add to the template are properly referenced in the project.

Pre-installed NuGet packages

UPDATE: The upcoming NuGet 1.5 feature will provide support for this feature in a way that doesn’t require the following harsh warning. Marcin Dobosz has a blog post detailing the feature.

Warning: I probably shouldn’t show you this next section and some of my co-workers may chide me on this. But if you promise to be responsible and pay close attention to the information and context for that information I’m about to show you, I’ll do it anyways and trust you not to inundate us with support calls when this blows your hand off.

The ASP.NET MVC 3 Tools Update includes very limited support for project templates that include NuGet packages. We originally wanted it to be very extensible, but ran out of time and imposed some severe limitations on the feature, hence the caution.

If you scroll to the bottom of the .vstemplate file, you’ll notice the following section:

<WizardData>
    <packages>
        <package id="jQuery" version="1.5.1" />
        <package id="jQuery.vsdoc" version="1.5.1" />
        <package id="jQuery.Validation" version="1.8.0" />
        <package id="jQuery.UI.Combined" version="1.8.11" />
        <package id="EntityFramework" version="4.1.10331.0" />
        <package id="Modernizr" version="1.7" />
    </packages>
</WizardData>

That is the list of NuGet packages that the MVC 3 project template installs when you invoke the project template.

But as I mentioned, there are two major limitations:

  • The package must exist in the %ProgramFiles%\Microsoft ASP.NET\ASP.NET MVC 3\Packages folder. MVC 3 doesn’t go searching online for them.
  • The version attribute of the package in the <package> element is required and is an exact match.

If you are fine with these limitations, you can modify this section of your custom project template to install the NuGet packages you care about. Just make sure they exist in the MVC 3 packages folder like I mentioned.

Once you are done making your changes, zip up the contents of the folder with the same file name you had before.

Registering your project template

At this point, all you need to do is copy the project template to the right location and add the appropriate registry entries. For extra credit, you can write an installer (MSI) that does all this for you.

The place to copy your template is the same place I mentioned previously, C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ProjectTemplates\CSharp\Web\1033

Once the template is there, you’ll need to setup the correct registry settings.

registry-editor

Since I’m lazy, I put these registry settings in a .reg file to make it easy to install. You’ll just need to modify the settings within the .reg file to match your project template.

32-bit

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\10.0\MVC3\
    ProjectTemplates\MyProjectTemplate]
"Title"="My Project Template"
"Description"="This is the coolest project template EVAR MADE."

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\10.0\
    MVC3\ProjectTemplates\MyProjectTemplate\C#\Razor]
"Path"="CSharp\\Web"
"SupportsHTML5"=dword:00000000
"SupportsUnitTests"=dword:00000000
"Template"="MyProjectTemplate.cshtml.zip"

64-bit

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\MVC3\
    ProjectTemplates\MyProjectTemplate]
"Title"="My Project Template"
"Description"="This is the coolest project template EVAR MADE."

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\
    MVC3\ProjectTemplates\MyProjectTemplate\C#\Razor]
"Path"="CSharp\\Web"
"SupportsHTML5"=dword:00000000
"SupportsUnitTests"=dword:00000000
"Template"="MyProjectTemplate.cshtml.zip"

The important thing to note are the options in the second registry section:

  • Path – Relative path from the ProjectTemplates folder. For C# projects, enter “CSharp\\Web”. For VB.NET use “VisualBasic\\Web”
  • SupportsHTML5 –Whether or not the project template supports HTML5. If set to 1, then the HTML 5 checkbox is enabled. That checkbox sets a project template variable, $usehtml5$. You can look at the default /Views/Shared/_Layout.cshtml inside of MvcWebApplicationProjectTemplatev3.01.cshtml.zipfor an example of this.
  • SupportsUnitTests – This allows you to associate a unit test project template with your project template.
  • Template – the name of your project template file.

The last step is to run the command devenv /installvstemplates to force Visual Studio to recognize the project templates.

I wrote a batch file, install.bat, when combined with the .reg file, that automates these steps.

cd %~dp0
regedit.exe /s project-template.reg
xcopy MyProjectTemplate.cshtml.zip "C:\Program Files (x86)\Microsoft Visual Studio   10.0\Common7\IDE\ProjectTemplates\CSharp\Web\1033" /Y
devenv /installvstemplates

For your convenience, I packaged up the necessary files in a zip file. Unzip the file, and run install.bat and you’ll see a new project template when you create a new ASP.NET MVC 3 project.

New ASP.NET MVC 3
Project

Pretty cool, eh?

By the way, I’m working on a book about ASP.NET MVC 3 with Brad Wilson, Jon Galloway, and K. Scott Allen. We’ve re-written large portions of the book in light of the new features that were released in ASP.NET MVC 3. If you’re interested, feel free to pre-order our book on Amazon.com!

Found a typo or error? Suggest an edit! If accepted, your contribution is listed automatically here.

Comments

avatar

42 responses

  1. Avatar for Justin
    Justin June 5th, 2011

    Phil nice tutorial. I really like the NuGet feature. Can't wait to see where you take it. Are you planning to allow for online searching and grabbing the latest version?

  2. Avatar for Mike
    Mike June 5th, 2011

    "I don’t expect that a large number of people will want to do this, which is one reason we haven’t spent a large amount of time making it easy (though that may change in the future)."
    This is all way to complicated! Please make it possible to add templates using NuGet. Then stop making templates and let the community make them.

  3. Avatar for Pop Catalin
    Pop Catalin June 5th, 2011

    Gotta love that registry hacking, reminds me of the 90s. Some Com/ActiveX hacking anyone?
    When will Visual Studio get a cleaner model for extensibility and get rid of registry all together. (Convention over Configuration? maybe)
    Seriously!

  4. Avatar for Colin Bowern
    Colin Bowern June 6th, 2011

    Seconding Pop's comment - it's clearly a hack for now. Hopefully we can stay aware from putting custom state in the Program Files folder. That's not what it was designed for. Visual Studio may put the out-of-box templates there, but that doesn't mean that user-generated content should be there unless they are willing to package it up in an MSI and distribute it properly.

  5. Avatar for haacked
    haacked June 6th, 2011

    @Colin I think the "right" way to add custom MVC project templates is to package it up in an MSI.
    The point of this blog post is to point those out there who want to write such an MSI in the right direction so they know what registry settings to add etc.
    The MVC team is investigating more loosely coupled tooling. I'll have more details in the future.

  6. Avatar for Scott Lance
    Scott Lance June 6th, 2011

    Phil, the download link appears to be broken

  7. Avatar for marcusswope
    marcusswope June 6th, 2011

    @Mike agreed, I think it could have been rewritten as:
    "I don’t expect that a large number of people want to do this, because we haven’t spent a large amount of time making it easy."

  8. Avatar for Anas Ghanem
    Anas Ghanem June 6th, 2011

    BTW, I noticed that when I create a new MVC 3 project using the standard templates, I see that it has a reference to "System.Web.Entity" assembly which is not required for MVC projects because the mentioned assembly contains the web form controls for entity framework (like the EntityDataSource control).

  9. Avatar for haacked
    haacked June 6th, 2011

    @Scott Doh! I fixed it.

  10. Avatar for Scott Lance
    Scott Lance June 6th, 2011

    @Phil Still getting a 404 :(

  11. Avatar for mrxliu
    mrxliu June 6th, 2011

    @Phil Still getting a 404 :(

  12. Avatar for Mike
    Mike June 6th, 2011

    "@Colin I think the "right" way to add custom MVC project templates is to package it up in an MSI."
    You think wrong. It should be:
    NuGet InstallTemplate AwesomeTemplate
    File > New Project > MVC > Awesome template
    Done!

  13. Avatar for JontyMC
    JontyMC June 6th, 2011

    We investigated creating our own project template and wanted to have that in a build process, ie you check-in a change and you get and MSI out from the build. There was far too much friction and we dropped the idea. The tight coupling of the tools to visual studio was the main issue. Would love to see more loose coupling!

  14. Avatar for moose
    moose June 6th, 2011

    I checked the rgistry, and I could not find le entries mentioned. The link for the zipped files is returning a 404

  15. Avatar for Scott Lance
    Scott Lance June 6th, 2011

    @Moose I didn't have the entries either, but I added them and the template showed up in the dialog.
    The issue I'm having now is that when it trys to create the project I am getting "The system cannot find the file specified (Exception from HRESULT: 0c80070002)"

  16. Avatar for dotnetchris
    dotnetchris June 6th, 2011

    @Phil I would completely disagree that a project template is best shared in a msi! The best way to share a project template would be nuget!
    Even the whole "but be very careful to make sure that any additions or deletions of content are reflected in the .vstemplate file. That file is a manifest of all the files within the VSIX package that makes up the project template." This sounds like native nugget right there. /endrant
    --Question--
    For how poorly of a scenario the installed packages feature of project templates work, what about this scenario? Instead of using that metadata to define the package relationship what about directly installing the packages into the template and manually creating and linking the packages file? Such that when the template is activated as a new project, you can just run update on the installed packages.
    Is it possible for a project template to be able to create/update the packages folder that would be at the root level?

  17. Avatar for haacked
    haacked June 7th, 2011

    Hi all, I fixed the 404. Many apologies for that!
    @Mike, @Chris. I was speaking in the present tense. I would love to be able to do it via NuGet, but it's sort of out of scope of what NuGet + VS can do today. Yes, it might be possible to hack it with an Install.ps1 script, but I cannot condone such behavior and you didn't hear that from me. ;)
    Another approach you can do today is have a nuget package contain everything you want in the project template. Our NuGet.Server package is a good example of this. Create an empty ASP.NET application, install NuGet.Server.
    Given the approach I show here, you could have a completely empty MVC project template and have it pre-install a NuGet package that has everything you want.
    @Chris today, the project template won't go online to install the package. We're looking into enabling more such scenarios in the future.

  18. Avatar for Guy
    Guy June 7th, 2011

    Even with the limitations, I very much like the ability to reference nuget packages from a vstemplate file.
    My project team makes heavy use of project templates; It would be nice if this feature applied to all vstemplate files - appears to be specific to just the MVC3 wizard.
    Any plans for this feature to migrate into general use?

  19. Avatar for jim
    jim June 7th, 2011

    about your upcoming book...can i order using paypal as mode of payment?

  20. Avatar for KevDog
    KevDog June 7th, 2011

    I continue to be amazed at the rude manners of people who think they have divined the one and true way to do things. Without doubt, software developers are the worst clients.

  21. Avatar for Gregg
    Gregg June 8th, 2011

    Dude....
    http://opensource.endjin.com/templify/
    Seriously, it's so much better than this approach.

  22. Avatar for Rad
    Rad June 9th, 2011

    I would like to know if I can add one or more projects from a Nuget package or Powershell console to the current solution (which can be empty) using one of available Project templates or a custom one I can bring from some storage location (local or remote). This is like a software factory where based on some DSL I can create a basic application (as multiple projects within the solution).
    Similar to this "design time/IDE" experience, I would like to know if I can do this outside of VS IDE and compose applications from Nuget packages, Source, T4 templates and compile once I have every piece in place. This is more like a product software factory.
    Thanks
    Rad

  23. Avatar for ulu
    ulu June 10th, 2011

    As far as I know, you can pack a custom action for your project template. This way, you can do anything you want, including downloading NuGet packages, checking current temperature in Austin, Texas, and other weird stuff. You'll have to make a bigger effort than downloading and applying a zip file though.

  24. Avatar for Leon
    Leon June 13th, 2011

    This is great stuff Phil.
    Much appreciated and just what I need at the moment.

  25. Avatar for Felix
    Felix June 18th, 2011

    So, I removed Microsoft js files from both Scripts folder and from vstemplate file. However, when I create a new project, I am getting an error popup "Unable to copy the file 'MicrosoftAjax.debug.js' from the project template to the project. Cannot find file c:\[temp directory]\MicrosoftAjax.debug.js"
    Why would it try to pull MicrosoftAjax.debug.js?

  26. Avatar for haacked
    haacked June 22nd, 2011

    @Felix did you update the .CSPROJ file too?

  27. Avatar for Felix
    Felix June 22nd, 2011

    No
    :blushing:

  28. Avatar for Felix
    Felix June 25th, 2011

    I realize I am running the risk of looking like an idiot for the second time... I cannot add a folder and a file in it (adding empty folder works fine - but who needs empty folders :)
    so, I added to vstemplate

    <Folder Name="Content" TargetFolderName="Content">
    <Folder Name="images" TargetFolderName="images" >
    <ProjectItem ReplaceParameters="true" TargetFileName="picture.jpg">picture.jpg</ProjectItem>
    </Folder>

    <ProjectItem ReplaceParameters="true" TargetFileName="Site.css">Site.css</ProjectItem>
    </Folder>

    and to csproj:
    <Folder Include="Content\images\" />
    and
    <Content Include="Content\images\picture.jpg" />
    When I add a project, I get a friendly popup saying "Exception from HRESULT: 0x80041FEB

    Any advise?

  29. Avatar for haacked
    haacked June 25th, 2011

    @Felix Hmmm, take a look at the project template I supplied and look at how I did it.

  30. Avatar for Felix
    Felix June 26th, 2011

    Ouch! For images (and probably all other binary files) ReplaceParameters should be false, not true. Apparently, VS errors out trying to find the tokens.
    OK, in hindsight it is obvious (as everything else in hindsight) :) - but something more verbose than "HRESULT: 0x80041FEB" would be really nice.
    Hopefully, somebody will stumble upon this solution before tearing his hear out!

  31. Avatar for Jean-Claude
    Jean-Claude June 30th, 2011

    Cool stuff!
    Is there also a way to register my own Controller Templates so that they apear in the Add Controller Dialog?
    Thanks for any hint ;-)

  32. Avatar for Aaron Johnson
    Aaron Johnson September 28th, 2011

    When I click on the link in your update to Marcin Dobosz's blog post, it takes my back to this page. I believe this is the post you were intending to link to:
    blogs.msdn.com/...

  33. Avatar for haacked
    haacked October 2nd, 2011

    @Aaron thanks! I fixed the link.

  34. Avatar for Paul
    Paul October 2nd, 2011

    The template shows up for me but when I try to create a new project I'm also getting the error "The system cannot find the file specified (Exception from HRESULT: 0c80070002)". Does anyone know the solution for this?

  35. Avatar for Paul
    Paul October 3rd, 2011

    Got it to work after all - when you run devenv /installvstemplates from the VS2010 command prompt you need to right click and choose 'run as administrator'.

  36. Avatar for mitja.gti
    mitja.gti January 11th, 2012

    One note and one question Phil.
    I had a problem removing your template. Even when I removed the .zip file and the registry value, it kept showing in VS. At the end I found out that there were some additional keys present in registry. When I removed them, the template went *puff* :)
    [code]HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\10.0_Config\MVC3\ProjectTemplates\MyProjectTemplate
    HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\MVC3\ProjectTemplates\MyProjectTemplate
    HKEY_USERS\S-1-5-21-...\Software\Microsoft\VisualStudio\10.0_Config\MVC3\ProjectTemplates\MyProjectTemplate[/code]
    And a question... I removed jQuery package tags from vstemplate (added CDN) but the files are still copied into the solution when I create it. Can one remove default NuGet packages?
    Thank you.

  37. Avatar for haacked
    haacked January 11th, 2012

    @Paul yeah, make sure to run my script as admin.
    @mitja.gti you need to run devenv /installvstemplates after. Make sure to run as admin.

  38. Avatar for mitja.gti
    mitja.gti January 12th, 2012

    @Phil I'm afraid I've already tried that without a success.

  39. Avatar for Christofer
    Christofer January 24th, 2012

    Great post, just what I was looking for.
    One thing though, adding your template works just fine running install.bat, it appears nicely in Visual Studio. However, when I try to create a new project using the template I get an error alert stating "The system cannot find the file specified. (Exception from HRESULT: 0x80070002)"
    I use Visual Studio 2010 under Windows 7 64-bit.
    Any ideas on what the reason for this error might be?
    MyProjectTemplate.cshtml.zip has been copied to the "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ProjectTemplates\CSharp\Web\1033" folder.
    Any input would be greatly appreciated!

  40. Avatar for striker
    striker May 18th, 2012

    "The system cannot find the file specified. (Exception from HRESULT: 0x80070002)"

    I have the same issue as Christofer is having.
    Any help is greatly appreciated.

  41. Avatar for Christopher HOlmes
    Christopher HOlmes January 8th, 2013

    I am getting the same issue ((Exception from HRESULT: 0x80070002)) Was this EVER resolved??? Why is this SO DIFFICULT!!!

  42. Avatar for Beton
    Beton May 9th, 2013

    Great stuff!
    As for today there is still no way of searchig the packages on NuGet (private) feed ?