Click here to Skip to main content
Email Password   helpLost your password?

Building and Deploying Web Application in .NET 2.0

"Building your .NET 2.0 web application is easy", you may have heard. Well, it depends on what do you mean by "build" and what do you mean by "easy". At my work place the system admins are spoiled into requiring all deployment be done with .msi files. What they want is click buttons to build the .msi file, run the .msi file on target machine and forget about it. It is developer's job to make sure all the projects are set up properly to accomplish this.

The hard way. To create *.msi file for web applications in Visual Studio .NET 2005, the "recommended" way is:

If you have done this before you will know it is a PITA. Come on, admit it, nobody is going to laugh at you. If you have a lot of web applications, doing the above for all of them is very frustrating and depressing. The part I hate most is customizing GUI in the installer project, in my opinion it is the worst piece of technology from Microsoft.

Now what can we do about it? I worked on this problem intensively for two whole days and came up with a General Installer project that works with every web application I have (cannot guarantee it will work with all of yours though). Here is the idea:

The easy way (for me anyway). To build and deploy a web application, here is all I need to do:

  1. Use "open website" menu to open my web application in Visual Studio.
  2. Use "publish website" menu to create a precompiled website in a selected folder.
  3. Open the General Installer project and the precompiled website in Visual Studio.
  4. Modify Deploy.xml file for my web application.
  5. Add the precompiled website to the installer project as project output. Build.
  6. Run GeneralInstaller.msi on target machine.

The above steps could take a whopping 20 minutes the first time you do it. Note that you don't need to create an installer project for each web application you want to deploy. If you wish, you can make a copy of the General Installer project for each web application and customize it.

Use included batch file. Instead of running GeneralInstaller.msi directly, it is much easier to run the included batch file GeneralInstaller.bat. This file must be placed in the same folder as GeneralInstaller.msi. Using this batch file, you can install the same web application multiple times on the same machine, there is no need to uninstall a previous version.

Deploy to VISTA. If you run either the batch file or the .msi file on a VISTA machine, you will get access denied error. This can be blamed on UAC, of course. What you need is open an Administrator Console (if you don't know how, remember "Google is your friend") and run the batch file from there.

The Details

General Installer. This project is a regular windows setup project generated from Visual Studio 2005. I removed all GUI except the progress bar (you can remove that, too). Then I added two files to this project: DeployHelper.dll and Deploy.xml.

Deploy Helper. This project is a library which contains two classes: ApplicationConfiguration and CustAct. The first class is derived from System.Windows.Forms.Form which handles GUI. The second is derived from System.Configuration.Install.Installer.

The purpose for this library is to relieve the pain of customizing GUI in installer project. It also does a lot of other things which I am not going to describe in this article. Now you have full control of everything. Here is the windows form in this DLL.

GeneralInstaller3.jpg

Target Dir is the physical folder for the current web application.

App Name is the application name in IIS.

Web Site dropdown is used to select one of the available websites on the target machine.

Virtual Dir is the name of the virtual directory in IIS, if you leave this field empty, the web application will be installed on the root of the selected website.

Config File dropdown allows you to pick a file as web.config file for the current web application (it will replace web.config with the file you selected).

Finally, if you want to reset IIS, check the Reset IIS box before clicking the Confirm button.

Deploy.xml. Here is a sample copy of this file. It is used to store default values for the current installation.

<?xml version="1.0" encoding="utf-8" ?>
<Configuration>
    <TargetDir>c:\TestWeb</TargetDir>
    <AppName>TestWeb</AppName> 
    <WebSite>Default Web Site</website> 
    <VirtualDir>TestWeb</VirtualDir>
    <WebConfigReplacement>true</WebConfigReplacement>
    <AppPool>.NET 2.0 Apps</AppPool>
    <DefaultDoc></DefaultDoc>
</Configuration>

Web Application Configuration

If you have only one configuration file (web.config) for all environments, then you need to set the WebConfigReplacement value in Deploy.xml to false.

I assume all configuration settings for a web application are stored in web configuration file. For each different environment, you should have a different web configuration file. These files have to be named like web_test.config, web_prod.config, etc. Otherwise DeployHelper.dll cannot handle it. You can modify DeployHelper.dll to handle configuration settings any way you want.

Note. There are a lot of other options you can set in Deploy.xml file, you need to look in the source code of DeployHelper.dll to find out.

For example, you can specify the name of your preferred application pool in the AppPool element of Deploy.xml. If an application pool with given name is found during deployment, your application will be assigned to this application pool (application pool assignment works only with IIS v6.0+).

Another example is you can specify a default document for your web application in the DefaultDoc element.

Possible Issues

History

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
QuestionI got dizzy
ulai
23:36 19 Oct '08  
I just learned Smile to used asp.Net
When i want to displayed it to my friend in his computer,it didn't showConfused
Could you tell me the detailed steps ?
GeneralWhy not just copy the files to the production directory?
ToddHileHoffer
3:25 11 Sep '08  
Am I the only person who simply copies the files the production directory?

I didn't get any requirements for the signature

GeneralRe: Why not just copy the files to the production directory?
Xiangyang Liu ???
3:38 11 Sep '08  
Yes! I would love to do that. But I am not allowed to come within two miles of the production servers nor can I remotely logon, except when there is a serious production issue that causes the whole website shutdown. Smile


GeneralRe: Why not just copy the files to the production directory?
ToddHileHoffer
3:55 11 Sep '08  
That makes sense.

By the way, I'm using a global error handler class that emails me when an error occurs. I have found that if I don't pre-compile and I copy the source, I get the actual line number of the code that caused the exception in the exception message. It makes life easy.
JokeRe: Why not just copy the files to the production directory?
Xiangyang Liu ???
6:49 11 Sep '08  
ToddHileHoffer wrote:
By the way, I'm using a global error handler class that emails me when an error occurs. I have found that if I don't pre-compile and I copy the source, I get the actual line number of the code that caused the exception in the exception message. It makes life easy.

Can user see the exception? I hope you don't have exceptions like the following:

Error in line 101 of source file Login.aspx.cs:
User 'Admin' failed to login.
The password '1234' does not match the value 'password' in the database.

Big Grin


GeneralRe: Why not just copy the files to the production directory?
ToddHileHoffer
7:48 11 Sep '08  
LOL, no we redirect the user to an error page. What's funny though is I have seen the asp.net error page on commercial sites. I even saw it on Microsoft.com once.

I didn't get any requirements for the signature

GeneralWeb Deployment Project
rippo
4:45 10 Sep '08  
Have you used Web Deployment Project for VS2005? It supports Pre/After build events, files to exclude etc. Very good


http://msdn.microsoft.com/en-us/asp.net/aa336619.aspx[^]
GeneralRe: Web Deployment Project
Xiangyang Liu ???
5:10 10 Sep '08  
rippo wrote:
Have you used Web Deployment Project for VS2005?

Yes, some extra work, almost useless, IMHO.


GeneralBrowserDialog violates the COM requirements for an STA thread, it must pump a message loop
Philip Wagenaar
2:50 29 Aug '08  
I was encountering some issues when running your code with my own additions for the ApplicationPool creation on a 64 bits system. I asked about it in a 64 bits forum, because I thought the code was just fine. The problem was that when I enable the "New Folder" button on the BrowseFolderDialog it worken on 32 bit systems but not 64 bit systems.

There they told me that the code for the BrowserDialog violated COM requirements and that it should stay within the same thread. I`ll adjust this in the code I am using now. But I thought I'd let you know. By the way, the forum post can be found at: http://forums.msdn.microsoft.com/en-US/netfx64bit/thread/d5d0eb76-c1f9-450a-ac76-055f50c65bc2/[^]

I also posted at the IIS forum because it seems that the write permission is incorrectly set for the Virtual Directory on 64 bit systems. But that post is pending moderation. I`ll also post that link when the post is approved.

Philip Wagenaar

GeneralRe: BrowserDialog violates the COM requirements for an STA thread, it must pump a message loop
Xiangyang Liu ???
4:44 29 Aug '08  
I hide the Make New Folder button on folder browse dialog because I think it is not needed. If you specify TargetDir as c:\NonExistentParentFolder\MyFolder, it will work fine: all parent folders will be created for you.

Thanks.


GeneralRe: BrowserDialog violates the COM requirements for an STA thread, it must pump a message loop
Philip Wagenaar
4:52 29 Aug '08  
ok, but thread issue still exists.

Philip Wagenaar

GeneralRe: BrowserDialog violates the COM requirements for an STA thread, it must pump a message loop
Xiangyang Liu ???
7:53 29 Aug '08  
Philip Wagenaar wrote:
ok, but thread issue still exists.

???

The following lines make the Folder Browser Dialog run in a STA thread:
Thread thread = new Thread(new ThreadStart(BrowseDialog));
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();



GeneralRe: BrowserDialog violates the COM requirements for an STA thread, it must pump a message loop [modified]
Philip Wagenaar
1:36 3 Sep '08  
Check out the latest post in this thread: http://forums.msdn.microsoft.com/en-US/netfx64bit/thread/d5d0eb76-c1f9-450a-ac76-055f50c65bc2/[^]

The reason I posted the problem was because the dialog is not working on Windows 2003 64 bits server

Philip Wagenaar
modified on Wednesday, September 3, 2008 6:44 AM

GeneralRe: BrowserDialog violates the COM requirements for an STA thread, it must pump a message loop
Xiangyang Liu ???
6:02 3 Sep '08  
Can't help you there. Never had a chance to play with a 64 bit server.


GeneralDeploy.xml changes ignored
Philip Wagenaar
12:53 27 Aug '08  
Changes in the Deploy.xml after building the project are ignored. Is this by design?

It's also very easy to add code to create and configure applications pools:

http://msdn.microsoft.com/en-us/library/ms525598.aspx[^]

Philip Wagenaar

GeneralRe: Deploy.xml changes ignored
Xiangyang Liu ???
14:35 27 Aug '08  
After building, a copy of deploy.xml file is packaged into the .msi file. So if you change the file again, you need to rebuild.

Philip Wagenaar wrote:
It's also very easy to add code to create and configure applications pools

I will take a look to see if I can add a feature to my tool. Thanks.


GeneralRe: Deploy.xml changes ignored
Philip Wagenaar
22:11 28 Aug '08  
Would be nice if you could place Deploy.xml in the same folder as the MSI and if so it would overrule the Deploy.xml packaged into MSI itself at runtime.

I tried to add this myself but I haven't found a fail proof way to always find the folder where MSI is located.

Philip Wagenaar

GeneralRe: Deploy.xml changes ignored
Xiangyang Liu ???
7:56 28 Aug '08  
Hi, Philip. I updated the code to add support for Application Pool Assignment. If you specify the name of your preferred pool in the <AppPool> element in deploy.xml, then your web app will be assigned to that pool. The assumption is IIS 6.0 is used and the app pool already exists (the code does not create a new app pool).


GeneralRe: Deploy.xml changes ignored
Philip Wagenaar
22:06 28 Aug '08  
Nice!

I already added it myself to your example. I also added code to create an Application Pool and set some custom settings for the Application Pool that are specific for my situation:

                    DirectoryEntry newpool;
DirectoryEntry apppools = new DirectoryEntry(metabasePath);
newpool = apppools.Children.Add(appPoolName, "IIsApplicationPool");
newpool.CommitChanges();

newpool = new DirectoryEntry(metabasePath + "/" + appPoolName);

//newpool.Properties["PeriodicRestartMemory"].Value = "0";
//newpool.Properties["PeriodicRestartPrivateMemory"].Value = "0";
newpool.Properties["PeriodicRestartSchedule"].Value = "03:00";
newpool.Properties["PeriodicRestartTime"].Value = "0";
newpool.Properties["IdleTimeout"].Value = "0";

newpool.CommitChanges();
A list of all available properies can be found at:
http://msdn.microsoft.com/en-us/library/ms525950.aspx[^]

Philip Wagenaar

GeneralRe: Deploy.xml changes ignored
Xiangyang Liu ???
2:06 29 Aug '08  
Philip Wagenaar wrote:
I already added it myself to your example.

I added similar code to create the app pool if it is not there already, after that, I thought about it: Sicne the pool is meant to be shared, logically it should probably be created separately. Plus some parameters/properties of the pool need to be configurable, if I put those in Deploy.xml file, there is a risk of installing one application will over-write things set by the installation of another application.


GeneralRe: Deploy.xml changes ignored
Philip Wagenaar
2:45 29 Aug '08  
I always create a seperate AppPool for each applications. You could also check if the AppPool already exists. But then you might just be re-writing IIS Manager into your setup Smile

Philip Wagenaar

GeneralRe: Deploy.xml changes ignored
Xiangyang Liu ???
3:41 29 Aug '08  
Philip Wagenaar wrote:
But then you might just be re-writing IIS Manager into your setup

It feels like it now. I better stop. Smile


RantA MSI for web site projects?
kjmcsd
4:41 26 Aug '08  
Unless you are in a crazy environment where a system administrator(who knows absolutely nothing about web apps) is installing web applications, which should not be the case 99% of the time, MSI is useless
I don't even think you can make a MSI install unattended yet so there is less of a use for them.

Great Atricle but I think you might be in the few who even uses installer projects for web apps.
GeneralRe: A MSI for web site projects?
Xiangyang Liu ???
5:12 26 Aug '08  
How do you deploy a web application? Just wondering.

I don't like .msi file myself, but we have been required to use it for our web applications. It does sound simple for system administrators and it can be made unattended, too (although we have administrators install manually).


GeneralRe: A MSI for web site projects? (Add connection string to MSI or use Wizard install on first time)
Philip Wagenaar
10:40 26 Aug '08  
I also agree that MSI installation of an ASP.NET application can make deployement more simple. Of course it might not be suiteble for all situations.

For example, if you need to register DLL's, set up database connections and test the connection you could include these in your Custom Actions.

Another way would be to create a wizard install that is shown the first time you start your ASP.NET application:
http://www.codeproject.com/KB/aspnet/WebInstaller.aspx[^]

Philip Wagenaar


Last Updated 9 Sep 2008 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010