Introduction
and Goal
In this article we will discuss about 3 important
features provided by VS 2010 to ease our deployment task on production and other
environment. We will first start with understanding problems with deployment and
then move ahead by creating packages , one click deploy and web.config
transformation.
Please feel free to download my free 500 question and answer eBook which covers
.NET, ASP.NET, SQL Server, WCF, WPF, WWF@ For more details Click
here .
Problems with deployment
When we talk about deployment it's not just
compiling and shipping DLL's to the production server. It involves lot of other
things like IIS settings, SQL scripts, text file, configuration etc.
As a developer you would like to give a package to the administrators to install
with all the dependencies or you would like to install the same from your visual
studio IDE itself.
The
Package and "MSDeploy"
Package is nothing but a ZIP file which has all the
necessary components (DLL, SQL Scripts, configuration files, IIS settings etc)
needed by your application.
To create package, click on project properties tab you will
find two tabs 'package/publish web' and 'package / publish SQL'. The first tab
has all the IIS and general settings while the SQL tab is for deploying SQL
Scripts on production.
The Package and publish web tab has certain key things which you can define from
IIS stand point and what should go in the package. Below figure describes some
important key features.
The "Package/Publish SQL" tab helps you to configure everything what is related
to SQL Server. The first point is you can import "web.config" file and all the
connectionstrings of the web.config is taken to generate the SQL scripts.
You can also specify source and destination of SQL server for the package. The
source destination is imported from the "Web.config" automatically, but you can
always go and change it as per your requirements.
There are three more points in the "Package/Publish SQL" tab:
You can see the auto-generated schema, in other words the schema is generated
automatically from specified source SQL Server.
If you want to go and add some scripts manually, like insert dummy data etc, you
can always use the 'add script' tab as shown in the figure.
The final thing which I personally love is that you can sequence how the scripts
should run. For instance in the below figure first the auto generate schema SQL
will run and then 'indexes.sql' script will execute. This is a nice feature to
exploit from versioning stand point.
In order to create the package, click on build deployment package menu and you
should see the necessary package files in your project package folder.
Ok, now the package is generated, let's understand how we
can go and install the same. To install the package we need the Microsoft web
deploy software. Microsoft web deploy a.k.a "msdeploy" was created by Microsoft
IIS team to migrate from IIS 6 to IIS 7.
To leverage its power it's used as a back bone to install the package created by
VS 2010.
If you remember the package folder created in the first step has some XML files.
There are three files which are very important one is the source manifest,
destination manifest and a cmd file. The manifest file is read by MS deploy for
Meta data and deployment configuration and later these all things are executed
via the cmd file.
The first thing you would like to do is check if the package is right and it
will execute properly on the environment. To do a trial installation you need to
go to "Microsoft Web Deploy" command and execute the cmd file with "/t". This
does not actually install but does a brief check of whether there can be any
issues while actual installation.
C:\Program Files\IIS\Microsoft Web Deploy>E:\deleteit\MyWebApplicationToPackage\
MyWebApplicationToPackage\obj\Debug\Package\MyWebApplicationToPackage.deploy.cmd
/t
Once you execute the cmd file you should see summary of changes which will take
place on your production server as shown in the below figure.
Once you have cross checked, you can deploy the package by using "/y" attribute
as shown in the below snippet. If you run your package using the 'y' command it
should create the IIS applications as well execute necessary database scripts to
create SQL Server objects.C:\Program Files\IIS\Microsoft Web Deploy>E:\deleteit\MyWebApplicationToPackage\
MyWebApplicationToPackage\obj\Debug\Package\MyWebApplicationToPackage.deploy.cmd
/y
HTML clipboardThe one click deploy
Many times you would like to install the package from the VS IDE itself rather than giving it to administrators for installing. In order to achieve
the same VS 2010 IDE has something called as 'One click deploy'.
As the name says, you can deploy your package in one click in different modes by clicking on 'Build' and then
'Publish' menu. Below is the screen shot of how the one deploy publish looks like. You can publish on FTP. Web
deploy, file system etc.
The final feature which is worth discussing is the 'Web.config'
transformation. Many times you have different config files for different
environments. It causes of lot of confusion when it comes to handling different
versions of web.config files.
So go to tools Configuration manager and add a new config file as shown in the
below figure. You can see that it creates a parent 'Web.config' files which can
be overridden by child config files with their own settings.
In order to see your newly added configuration you need to right on the
web.config file and click 'add config transforms' as shown below.
Depending on your active configuration selected the appropriate 'Web.config'
will be created for the environment.
One of the questions which will come to your mind is how to
do the transformation in the child web configuration file. In other words your
parent web config file has a connection string how can we override/ transform
the same in the child config files like production, acceptance, test etc.
The transformation of the config file is a two step process first is to
search/locate what needs to be transformed and second to do the actual
transformation.
There are 3 types of mechanisms by which you can search/locate a particular
property / element Match, Condition and XPath. There are eight ways by which you
can set / replace / transform the searched property or element as shown in the
above figure.
Let's take one example how the search and transform works. Below is an image
code snippet of the parent 'web.config' file and a child file having 'web.production.config'
file.
We want to change the connection string to a different value for the production
environment. You can see in the below code snippet the production environment
config file has used "xdt:locator" to search by 'name' and then we want to set
the attribute to a different value so we have used 'setattribute'
transformation.
More Details of Locaters and Transformation
Let's have a cursory look on the 3 locators and 8 transformations.
All the below stuff I have ripped from
http://vishaljoshi.blogspot.com/2009/03/web-deployment-webconfig-transformation_23.html.
xdt:Locators
The inbuilt xdt:Locators are discussed below.
Match
In the provided syntax sample below the Replace transform will occur only
when the name Northwind matches in the list of connection strings in the source
web.config.Do note that Match Locator can take multiple attributeNames as
parameters e.g. Match(name, providerName) ]
<connectionStrings>
<add
name="Northwind"
connectionString="connectionString
goes here" providerName="System.Data.SqlClient"
xdt:Transform="Replace"
xdt:Locator="Match(name)"
/>
</connectionStrings>
Condition
Condition Locator will create an XPath predicate which will be appended to
current element's XPath. The resultant
XPath generated in the below example is "/configuration/connectionStrings/add[@name='Northwind
or
@providerName=' System.Data.SqlClient' ]"
This XPath is then used to search for the correct node in the source
web.config file.
<connectionStrings>
<add
name="Northwind"
connectionString="connectionString
goes here"
providerName="System.Data.SqlClient"
xdt:Transform="Replace"
xdt:Locator="Condition(@name='Northwind
or @providerName='
System.Data.SqlClient')"
/>
</connectionStrings>
Xpath
This Locator will support complicated XPath expressions to identify the
source web.config nodes. In the syntax
example we can see that the XPath provided will allow user to replace
system.web section no matter where it is
located inside the web.config (i.e. all the system.web sections under any
location tag will be removed.)
<location
path="c:\MySite\Admin"
>
<system.web
xdt:Transform="RemoveAll"
xdt:Locator="XPath(//system.web)">
...
</system.web>
</location>
xdt:Transform
Replace
Completely replaces the first matching element along with all of its
children from the destination web.config (e.g. staging environment's web.config
file). Do note that transforms do not modify your source web.config file.
<assemblies
xdt:Transform="Replace">
<add
assembly="System.Core,
Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"
/>
</assemblies>
Remove
Removes the first matching element along with all of its children
<assemblies
xdt:Transform="Remove"></assemblies>
RemoveAll
Removes all the matching elements from the destination's web.config (e.g.
staging environment's web.config file).
<connectionStrings>
<add
xdt:Transform="RemoveAll"/>
</connectionStrings>
Insert
Inserts the element defined in web.staging.config at the bottom of the
list of all the siblings in the destination
web.config (e.g. staging environment's web.config file).
<authorization>
<deny
users="*"
xdt:Transform="Insert"/>
</authorization>
SetAttributes
Takes the value of the specified attributes from the web.staging.config
and sets the attributes of the matching
element in the destination web.config. This Transform takes a comma
separated list of attributes which need to
be set. If no attributes are given to SetAttributes transform then it
assumes that you would like to Set all the
attributes present on the corresponding node in web.staging.config
<compilation
batch="false"
xdt:Transform="SetAttributes(batch)">
</compilation>
RemoveAttributes
Removes the specified attributes from the destination web.config (i.e.
staging environment's web.config file).
The syntax example shows how multiple attributes can be removed.
<compilation
xdt:Transform="RemoveAttributes(debug,batch)">
</compilation>
InsertAfter (XPath)
Inserts the element defined in the web.staging.config exactly after the
element defined by the specified XPath
passed to "InsertAfter()" transform. In the syntax example the element
<deny users="Vishal" />will be exactly
nserted after the element <allow roles="Admins" /> in the destinationXML.
<authorization>
<deny
users="Vishal"
xdt:Transform="InsertAfter(/configuration/system.web/authorization/allow[@roles='Admins'])"
/>
</authorization>
InsertBefore (XPath)
Inserts the element defined in the web.staging.config exactly before the
element defined by the specified XPath
passed to "InsertBefore()" transform. In the syntax example the element
<allow roles="Admins" />will be exactly
inserted before the element <deny users="*" />in the destinationXML.
<authorization>
<allow
roles=" Admins"
xdt:Transform="InsertBefore(/configuration/system.web/authorization/
deny[@users='*'])" />
</authorization>