Friday, July 31, 2009

App_Code folder doesn’t work with Web Application Projects (WAPs)

As you might already know we have two different project types for web development  in Visual Studio 1.) Web Application Projects (WAPs) 2.) Web Site Projects (WSPs)…

Often time developers hear that if you want to put a random class file in your web project you should put it in App_Code folder.  While this is true for Web Site Projects (WSPs), it is not so much true for Web Application Projects (WAPs) and in this post I will try to explain the inner workings on why that is the case…

Firstly App_Code folder is a special ASP.NET RUNTIME folder…  Any files in this folder are compiled by ASP.NET when your site is actually running on the server...  This essentially allows you to drop random class/code files in this folder to be compiled on the server side…  For this very reason if you drop something new into the App_Code folder of your running web site, it is like resetting it coz ASP.NET runtime now recognizes that there is a new class which needs to be kept in consideration during running the site…  This magical folder brings with itself various connotations when it comes to different project types…

First of all it is important to know that Visual Studio does not really create any DLLs when you are using Web Site Projects (even when you are building the web site)…  VS simply validates that your code is correct in WSP… In Web Application Projects (WAPs) this is not actually true as VS actually creates a DLL with all the code behind and class files that are present in your project and drops them into the BIN folder of your project…

In case of WAPs every file in the project is marked with a specific “Build Action” as shown below:

image

All the class files (.vb/.cs) are marked as “Compile”… This essentially tells VS to take all those files and call the correct VB/C# compilers on them…  The result of that activity is the DLL,which is named same as your project name i.e. WebApplication1.dll, being created in the BIN folder of your project…

With this understanding let us look at right click Add—> Add ASP.NET Folder --> options on Web Application Project

image

You will notice that App_Code folder is not really available as an option… This is an intentional behavior… 

If you add a App_Code folder into a Web Application Project and add classes to that folder then more than likely their “Build Action” will be marked as “Compile” (as all .vb/.cs files are defaulted to “Compile”)… This will signal Visual Studio to compile them inside the IDE to produce the DLL in the BIN folder…  For illustration let us assume you added a class called Products in App_Code\Products.cs file which is marked as “Compile”… Now when you build your WAP you will get a DLL in your project BIN (e.g. WebApplication1.dll), which when you open in ILDASM or Reflector will tell you that Product class exists in it…

Now when you try to run the project locally or do a xCopy deployment of your WAP to the server you will might accidentally move the App_Code\Products.cs on the server as well…  This is time when things start getting tricky… Now you have a DLL in the BIN which is provided as a reference to ASP.NET runtime which has the Products class… Also ASP.NET is trying to compile your App_Code folder (as it is a special Runtime folder and that is an expected behavior) which will result in duplicate declaration of your Product class (one in the referenced project DLL and second in the dynamic compilation)…  As you can imagine duplicate declaration of same type is not desirable…:-)

Additionally, VS will auto generate namespace for your Products class in the DLL to be something like WebApplication1.App_Code.Products vs ASP.NET runtime will produce a hashed version of the name space causing additional connotations giving you weird error messages…

So at a high level there are many reasons why App_Code folder is not supported for Web Application Projects and should be avoided…

Does this mean App_Code and WAPs just don’t ever work together?

No, that is not true… App_Code and WAPs can work together, you need to make sure that “Build Action” of none of the files in the App_Code folder is marked as “Compile”… Ideally you should mark them as “Content” which will ensure that they will get deployed on the destination and get compiled by ASP.NET instead of locally by VS IDE… 

But this will bring its own side effects that intellisense may not work very well for these files inside VS as they will not be treated as Class files by VS… But the key point is that you do not really need “App_Code in Web Application Projects (WAP) if you do not intend to put random code files or modify existing code files in App_Code folder directly on your production server…

What should one do if there are isolated code files which need to be added to WAPs?

You can add code files under any folder call it “CodeFolder”, “Controllers” or anything that makes sense in your project… Just avoid putting them under “App_Code” unless you specifically want the server side compilation behavior…

-Vishal

Exclude App_Data Folder from Deployment

SQL Server Express is a development time database and it is not recommended to use it on your production server.  The rationale for providing SQL Express edition was to ensure that development can be done without having to install a licensed copy of SQL Server on your development machine…

Additionally most of the hosters do not support SQL Server Express on their shared web servers and enterprises are typically running on full SQL Server in their Staging/Production environment.

When you are developing a Web Project using Visual Studio then your SQL Express MDF file is put inside App_Data folder.  VS also ensures that App_Data folder is set up with the correct read/write access so that your application can then write to the Database files in it… 

When it comes time to deploy your application you should ensure that your MDF files do not get deployed with the rest of your application.  To help with this VS provides option to exclude the content of App_Data folder.

Web Application Projects (VS 2005/ VS 2008)

If you are using Web Application Projects in VS 2005/VS 2008 then when your right click on your project and hit “Publish” then the option to Exclude the content of App_Data is available as a checkbox as shown below:

Publish WAP

Web Application Projects (VS 2010)

In VS 2010 web deployment is hugely improved… As part of the clean up this option is now moved to project properties as shown below:

image_thumb10

When project properties window opens then navigate to Package/Publish tab… In this tab there is a checkbox which allows you to exclude “App_Data” content while publishing…Check the box as shown below:

image_thumb11

With this setting Visual Studio 2010 will make sure that your Web Deployment does not includes content of App_Data folder… If you would like to learn more, check out the rest of the properties of Package/Publish tab

After setting this property it will get respected automatically while creating a web package or while using 1-Click Publish

Are there scenarios to not exclude App_Data folder all the time?

Sometimes I have been asked why to give a specific option to Exclude App_Data folder and not exclude it all the time by default.

Well people also put bunch of other files in App_Data folder for e.g. XML files which your web updates or other flat file DBs that your web might potentially use…  In this scenario excluding App_Data would exclude those files too and you would ideally want to avoid that, hence there is an explicit option to leave out the content of App_Data folder…

Hope this helps!!

-Vishal

Wednesday, July 29, 2009

Web Deployment Projects do not work after installing VS 2008 SDK

Some days back it was brought to our attention that Web Deployment Projects (WDP) stop working after installing Visual Studio 2008 SDK…  As you soon VS 2008 SDK is uninstalled then WDP again start working…

We narrowed down this issue to be due to “Isolated Shell Application” which come as part of VS 2008 SDK…  The work around to get WDP working again is to go ahead remove the Shell package by deleting the registry key below:

HKLM\Software\Microsoft\VisualStudio\9.0\Packages\{815946b0-1c0d-4eab-8226-36ea3c59162a}

If you would at anytime restore the Shell package functionality then it would be advisable to Export the registry key and save it somewhere (or repairing the VS 2008 SDK install should also do the same)…

If you have any concerns or issues please do not hesitate to write back to Vishal.Joshi@Microsoft.com

-Vishal

PS: Do note that although the WDP build reports failure with VS 2008 SDK installed the build is not really failing, it is just a reporting false failures, so it is not as severe as it sounds….

Thursday, July 09, 2009

10 + 20 Reasons why you should Create a Web Package

Before we talk about the reasons why you should create a Web Package let us first understand what is a web package… Web Package is an atomic, transparent, self describing unit representing your web application which can be easily hydrated into any IIS Web server to reproduce your web…  It is a .zip file which not only contains your content but also contains its dependencies like IIS Settings, Databases, GAC DLLs, Registry Keys etc…

The concept of creating Web Packages for deploying your web application to an IIS Web Server is recently introduced with Microsoft Web Deployment Tool (MsDeploy) and towards the end of this post I will talk about how you can create a Web Package for your web app… But before going there let me talk about the 10 reasons why you should consider creating web packages for your web application:

  1. Having all your web content and dependencies like IIS Settings & DB into a single .zip file allows you to easily transport it anywhere…
  2. If the web package actually contains source code then you can replicate your dev environment to another box relatively easily…  Imagine being able to recreate a project on your home machine by simply emailing yourself a .zip file…
  3. If you are deploying in a web farm environment then deploying the web package to various server boxes will allow you to very easily recreate your load balanced web servers…
  4. If you are creating software for community to use then sharing web package .zip files with world creates a common handshake model…
  5. Web Application Gallery, which will be common home to find reusable Web Applications also uses the same Web Package format… So you will have an opportunity to put up your web app into Web Application Gallery if you create a Web Package…
  6. Most of the Package creation process is very automated so you do not need to write custom actions like you would have to do in case of MSIs…
  7. Creation of Web Packages can be automated along with your nightly builds really easily using MsBuild with systems like Team Build…
  8. You can create a web package for various versions of your web application and easily use the versioned packages to roll back to any version you like…
  9. You get free standardized UI to install the Web Packages in IIS Manager which hopefully will become pretty standard and easy for everyone to understand…  If you do not like to use the UI the package can be installed via commandline as well…:-)
  10. Most of the automated tools (providers) required for packaging  your web application and its dependencies are available out of the box (few of which are IIS Settings, SQL DBs, Web Content, GAC assemblies, COM components, Registry keys etc)… 

Finally let me mention the out of the box providers which can be invoked when you want to package your web application…  You actually have a choice to call any of these providers depending on what parts of your Web Application you like to be packaged… These are my other +20 reasons why you should create a web package…

  1. File System Directory to move a files & folder which contains your web application files like .aspx, .config, images, .js, .css, .master etc – contentPath
  2. Creating a new IIS Web Application for your web– iisApp
  3. Moving IIS7 and above (read Vista, Win2k8, Win7, Win2k8 R2 and above) Configuration Settings associated with your web (e.g. Default Document, ApplicationPool Mapping etc) – appHostConfig
  4. IIS5.1 & 6 (read XP, Win2K3 compatibility)  Metabase Configuration Settings (parallel to IIS7+ settings above) - metakey
  5. Pulling data & schema from existing SQL Server Database or custom generated .SQL files which your web uses– dbfullSQL
  6. Any Security Certificates (e.g. SSL & ClientAuth) that your web depends upon- cert
  7. Any GACed assemblies like 3rd party controls or libraries that your web uses – gacAssembly
  8. Any custom IIS7+ Application Pool that your web has created– appPoolConfig
  9. Registry key associated with your webs – regkey
  10. 32 bit COM Object – comObject32
  11. 64 bit COM Object – comObject64
  12. Security ACLs associated with folder – setAcl
  13. Granular control by pulling just a registry value - regValue
  14. ASP.NET root web configuration file on 32 bit machine – rootWebConfig32
  15. ASP.NET root web configuration file on 64 bit machine – rootWebConfig64
  16. Similar type of support for packaging MySQL DB – dbMySQL
  17. Packaging Machine.Config of 32 bit machine – machineConfig32
  18. Packaging Machine.Config of 64 bit machine – machineConfig64
  19. If there is still a provider missing then you can very easily create one – yourCustomProvider
  20. A secret provider which I am not allowed to talk about just yet :-), but trust me it is really a killer provider - secretProvider

So now that you have 10 +20 reasons to create a web package let us talk about how to create one… From end developer/IT pro standpoint you can create Web Packages from various different avenues, some of which are:

Please follow the links above to create a web package using your preferred method… I hope you are jazzed about being able to archive and deploy your web applications using Web Packaging…

Tuesday, July 07, 2009

Importing a Web Package into IIS Manager

Today I am hoping to talk about installing/importing a Web Package into IIS using IIS Manager…

For this walkthrough you will first need a Web Package… If you want to get few ready made packages you can get them from Web Application Gallery…  There is also a MsDeploy package of BlogEngine.NET available on CodePlex, which you can download to try out this walkthrough…

Hopefully, eventually you will be creating your own web packages for deployment and this walkthrough will even apply at that time…  If you want to learn how to create a web package from Visual Studio 2010 then read the below posts:

To begin importing a web package into IIS using the new “Import Application” wizard you need to make sure that you have installed IIS Manager by going to Add/Remove Windows component…  You will also need MsDeploy installed over IIS, typically it will come with your VS 2010 installation but if you do not have VS 2010 just yet then you can download it from MsDeploy Download.

Today, I will install a Web Package of the sample ASP.NET 4.0 web application that I created earlier in the tutorial “Creating a simple ASP.NET 4.0 Web Site”…

To start importing the web package let us start IIS Manager (Start –> Run –> InetMgr)

I will be installing the web package under Default Web Site…  Although it is not required to install the package under Default Web Site, it can be installed under any Web Site of your choice… Also if the package created was a “IIS Web Site Package” then it could be installed under the server /sites node directly as well…  In anycase when we open the “Default Web Site” node then on the right side command bar you will now notice two new commands  1.) Export Application 2.) Import Application as shown below:

Import Application

On clicking “Import Application” on the first screen you will be asked to provide the path to web package (.zip file)… I will be providing the location of the sample web package which I created in the earlier tutorial:

image

On clicking next the Import Application wizard will display the content of the web package as below:

Package Content

Notice that in the above example the package wizard shows that the Web Package contains:

  1. IIS 7 Application - This will actually do the job of creating an IIS Application and mapping the virtual directory…  It will also move any additional IIS Settings associated with the web application…
  2. File System Content  - All the physical files (.aspx, .dlls etc) which need to be placed in the web site directory…
  3. Database – This is the database that I packaged into my web package

On clicking “Next” I will get a screen which I will call as the “Parameters” screen…  When you create a package using VS 2010, then VS identifies the key attributes of your web application which you need to customize and it creates MsDeploy parameters for the same…  All these parameters are something which you can modify during the package import process as seen below… Parameters Screen
In the above example notice that “Default Web Site” is read-only… This is due to the fact that the “Import Application” wizard was invoked from Default Web Site… I am now naming the Web As “SimpleASP4Web” and placing it under “C:\WebSites\SimpleASP4Web”…  Also note that I am using “SimpleASP4Web” DB on my local SQL Server…

The ConnectionString that I am providing in here will be used to deploy my packaged DB and will also be used to update my web.config file (this will happen only if the package was created to do so…  I will write a separate blog post on how to do that, but in future release of VS 2010 this option will be set by default when you create the web package at the first place…)

In any case now on clicking “Next” the Web Application installation will begin showing you a progress bar and hopefully within no time the web package will get installed showing you the status as below:

Installation Progress

On hitting “Finish” on this screen the web package will be installed and on inspecting the IIS Manager you can see that the package is actually successfully imported and web site is ready to go:

Deployed Web in IIS

On inspecting the SQL Server Management Studio you can also see the Simple ASP4Web DB also installed:

SimpleASP4Web DB

Hopefully you can see that the web deployment features with great UI options in VS 2010 and IIS will make the process of packaging and installing you web applications much easier than what it has been before…

-Vishal