Showing posts with label VS 10. Show all posts
Showing posts with label VS 10. Show all posts

Wednesday, July 13, 2011

Documenting Key End-to-End Deployment Scenarios

 

The IIS Web Deployment Tool (Web Deploy) and the deployment features introduced in Visual Studio 2010 enable you to automate many deployment tasks, but we have heard you all that many common scenarios not yet documented fully. We are addressing this need by creating step-by-step walkthroughs that will guide you from beginning to end through scenarios that address common real-world needs.

UPDATE:  We just published the Enterprise Deployment Series which can be found at:

Interestingly, remaining of this blog post is not the documentation of the solution but actual articulation of problem statements. This post presents the first set of scenarios that we have identified and solicit your feedback to help us determine they are representative enough or not. If you have any feedback as usual you can post them here as comments or feel free to send me an email at Vishal.Joshi@Microsoft.com.

Scenario 1: Enterprise Deployment with Continuous Integration

In this scenario, a solution that includes multiple web application projects is deployed to test, staging, and production environments, using a continuous integration process for staging and production.

Target Environments

The TESTING environment consists of a server that runs IIS 7.5 and a server that runs SQL Server 2008 R2. The developer machine has a network connection to the test servers, and the developer uses one-click publish to deploy to testing environment.

STAGING consists of a web farm (2 servers running IIS 7.5) and a database server that runs SQL Server 2008 R2. The developer machine has network access to a TFS server that acts as a source code repository, and the TFS server has network access to the staging servers. (The developer machine does not have direct access to the staging environment, and the developer does not have administrative rights on the staging servers.) Team Build builds the Visual Studio solution, runs unit tests, and publishes to staging. Each time that Team Build performs build and deployment, it simultaneously creates a deployment package (web deploy .zip file) for use in deploying to production.

The PRODUCTION environment mirrors staging except that a firewall (or perhaps even different domains) prevents direct access for publishing from the TFS server to production. When a build is approved for production, the IT department uses the package created when TFS publishes to staging to deploy to the production servers.

The diagram below illustrates this scenario:

Enterprise_Scenario_Diagram

Enterprise scenarios may have a QA environment set up in a manner similar to staging; however, for the purposes of demonstrating how to set up deployment it's not necessary to include that here, because the process would be similar to the process for setting up staging.

Visual Studio Solution

The Visual Studio solution to be deployed consists of multiple web application projects, a class library project, and a unit test project. Deployment must take into account the following considerations:

  • One of the projects uses ASP.NET membership functionality, and the membership database must be deployed. Account information can be deployed to test but not to staging or production.
  • One of the projects uses a SQL Server database that is accessed using the Entity Framework (Database First, using an .edmx file). On initial deployment to any environment, only the structure (schema) should be deployed. For any database deployment after the initial deployment, data already entered online in that environment must be preserved.
  • The class library project creates an assembly for a custom control that is used in one of the projects. This assembly needs to be installed in the GAC as part of the deployment process.
  • The custom control gets a default value from the registry. The registry value needs to be different in each environment and needs to be updated when the solution is deployed. (This particular use of registry settings is not common, but updating the registry is a common need, and this provides a simple way of integrating a registry update into the scenario.)
  • The Web.config file contains settings that must be different for debug vs. release builds, and settings that must be different for different target environments.
  • One of the web projects includes a folder for log files. The deployment process must not copy files in this folder from source to destination and must not delete files from the folder on the target server.
  • IIS settings for error handling and authentication must be set up on the target server during deployment. For the test environment these can be the same as the settings on the developer machine, but for staging and production the settings are different.

Some additional deployment considerations apply only to the automated deployment from TFS for staging and production:

  • Deployment should occur only if the unit tests are successful.
  • The web projects need to be precompiled before deployment.
  • The IIS settings for staging and production are taken from IIS on the TFS server. (This is a limitation of the current release of Visual Studio and Web Deploy; when the walkthroughs are updated for the next release of the software, hopefully IIS will not be required on the TFS server (keeping fingers crossed Smile)
  • App_offline.htm must be set up at the start of deployment and removed at the end.
  • Deployment activities should be logged. When deployment completes or fails, email notifications should be sent to designated recipients.
  • If deployment fails, the previous deployment's package should be redeployed, or the current deployment should be retried.
Tasks Illustrated

The walkthroughs for this scenario would guide you through the following tasks"

  • Downloading the Visual Studio solution to be deployed.
  • Setting up the test server.
  • Using one-click publish to deploy to testing servers:
    • Initial deployment.
    • Redeployment without a database change (for example, an update to code in a web page).
    • Redeployment after making a database schema change.
  • Setting up staging and production servers.
  • Setting up the build server.
  • Three deployments to staging (initial, web page change, database change).
  • Three deployments to production (initial, web page change, database change).

For the Visual Studio 2010 version of the walkthrough, database updates will involve running custom SQL scripts as part of the deployment. The scripts will be created manually; tools such as TSData and Red Gate can be used to generate such scripts, but those tools will not be covered in these walkthroughs. Eventually we will look at smoothing this flow as well.

Scenario 2: Enterprise Deployment for MVC and Entity Framework Code First

This is a variant of the first scenario that differs from it in the following ways:

  • The web projects are MVC instead of Web Forms.
  • Entity Framework Code First is used instead of Database First (no .edmx file).
  • TeamCity is used instead of TFS.

Scenario 3: Enterprise Deployment for Web Site Projects

This is another variant of the first scenario that differs from it in the following ways:

  • The web projects are web site projects instead of web application projects or MVC.
  • Web Deployment Projects (WDP 2010) are used.
  • One-click publish is not available for web site projects, so a web deployment package is used for deploying to test.

For those of you who work in enterprise environments, do these scenarios adequately represent the kinds of challenges you face in deploying ASP.NET web applications? Are any key pieces missing? We cannot answer every question in these walkthroughs, but if there are other issues commonly faced by your team, we can add solutions for them to the walkthroughs as well.

Your thoughts and feedback are welcome.  Also I want to thank Tom Dykstra, Bilal Aslam & Sayed Hashimi on our team who will be helping on putting together a lot of this content for you.

FEB 2012 UPDATE:  The work on these scenario documentation has started happening.  The tutorials are still being written but the sample app with an initial draft of the first part of the tutorials is available on MSDN:

http://code.msdn.microsoft.com/ASPNET-Enterprise-Web-6b2ad7cf

(The tutorials are in Word docs in a folder in the sample project.)

They’ll be published on the ASP.NET site most likely in the next couple of months.

Thanks for reading!!

-Vishal

Wednesday, June 15, 2011

Announcing HTML5 & CSS3 support for Visual Studio 2010 SP1

image

Since the last few months it feels like web standards are moving at pace that we would really like them to move. Every browser is pushing the envelope ahead including our very own IE9. For the first time it feels like web is getting the extra freedom of expression that it deserves and we want to contribute to that.

ASP.NET developers have been asking for HTML5 & CSS3 support all the time and today we are super excited to announce the public availability of Visual Studio Web Standards Update which brings a ton of HTML5 & CSS3 support to Visual Studio 2010 SP1. VS Web Standards Update is a free extension available for anyone who is using Visual Studio 2010 SP1 and it provides HTML5 & CSS3 support based on current W3C specifications.

clip_image001

HTML5

clip_image004

VS Web Standards Update provides you intellisense and validation for most common HTML 5 features like:

· Video & related tags

· Audio & related tag

· New input types like email, url, date etc

· Drag & Drop support

· Accessibility standard WAI-ARIA

· Microdata

· Schema.org & more SEO friendly goodness

·

Browser APIs

· Geo-Location - Having location aware websites is growing trend and now you will have full intellisense and validation within Visual Studio for creating websites which are location aware. For sample view the source for the IE9 test drive demo.

· Local Storage – IE has been supporting local storage from IE8 onwards, now Visual Studio will provide you with full fidelity intellisense to create sites which can save state within browser. For sample of try view source on HTML5 Demo Site

CSS3

clip_image005

This update supports intellisense and validation for most of the CSS3 modules including:

· 2D Transforms

· 3D Transforms

· Animations

· Background & Borders

· Basic Box Model

· Basic UI

· Behavior

· Color

· Flexible Box Layout

· Fonts

· Generated Content for Paged Media

· Hyperlink Presentation

· Line

· Lists

· Marquee

· Media Queries

· Multi Column

· Namespaces

· Paged Media

· Presentations Levels

· Ruby

· Selectors

· Speech

· Syntax

· Template Layout

· Text

· Transitions

Additionally, if you are trying to make websites which work on a variety of platforms and browsers you will love the fact that Web Standards Update not only supports IE specific prefixes like –ms; but also other vendor prefixes like –webkit and –moz.

With all of the above goodness we hope you all will enjoy this update as much as we did creating it and hope you will share the good news with our larger developer community.

Sharable Links

· Download URL - http://visualstudiogallery.msdn.microsoft.com/a15c3ce9-f58f-42b7-8668-53f6cdc2cd83

· VWD Team Announcement post by Mads - http://blogs.msdn.com/b/webdevtools/archive/2011/06/15/web-standards-update-for-visual-studio-2010-sp1.aspx

· Walkthrough post by Hanselman - http://www.hanselman.com/blog/AnnouncingTheWebStandardsUpdateHTML5SupportForTheVisualStudio2010Editor.aspx

Finally, I want to call out that this update is made feasible due to heroic efforts by a lot our team members working on their personal spare time, so please give a huge shout out to our team including Mads Kristensen, Peter Spada, Van Kichline, Aliaksei Baturytski, Damian Edwards, Barry Tang, Bala Chirtsabesan, Alex Gavrilov, Xinyang Qiu, Jon Jung, Scott Hanselman, Teri Schroeppel & Yong Lee.

Thanks again!!

Vishal R. Joshi | http://vishalrjoshi.com | @vishalrjoshi

PS: The Web Standards Update works on both VS 2010 SP1 and VWD Express 2010 SP1. Being a VS Extension, it does not support certain CSS3 selector syntax & Browser API intellisense which would require servicing the shipping bits.

Friday, November 05, 2010

Team Build + Web Deployment + Web Deploy + VS 2010 = Goodness

I have to confess this is one of the most requested blog post in Web Deployment via either direct emails, comments on the blogs, twitter, in conferences etc and it has been completely my bad to have prolonged this as long as I have. As it is said - better late than never, so without any delay let us get started.

In this blog post I am hoping to cover the topics of setting up your web deployment using Web Deploy (MsDeploy) and Team Build. When we talk about automated web deployment with Web Deploy (I love our naming J) there are multiple aspects that come into mind, let us clear few of the concepts before we proceed with the walkthrough:

· Web Packaging – Web Packaging is the process of creating a .zip file which can contain your web content (pages, images, CSS, JavaScript files etc), databases, IIS Settings, Application creation, ACLs etc. From your Team Build you can easily create Web Packages which you can ask your server admin or Test team to pick up and install on you web servers for testing. With Web Packages (.zip files) you will also get a .cmd file created by VS 2010 which can be run to install the package. There is not a direct automation to run this command file from team build but you can easily hook up post build step to execute the .cmd file if you would like to automate the installation of the package as well.

· Web Publishing – Web Publishing is the process of directly taking the source application (in Team Build case the sources are hopefully in your TFS source repository) and directly pushing it to the destination web server. In this case a .zip file is not created but if you would like that for archival then that is possible as well. If you want your web servers to have your latest web application installed in Continuous Integration (CI) fashion then Web Publishing is the direction I would recommend.

Note - Web Publishing can only work when you have your Web Servers configured to accept Web Deploy request. There is an earlier blog post about Setting up your Web Servers for Web Deploy, without having your Web Servers setup the below walkthrough (Publish Section) will not succeed so please make sure that you have your Web Servers configured correctly before proceeding.

Step 1: Get your TFS Build Server and Source Code Control Set up

I am going to assume that you have a license for VS 2010 TFS environment setup. Below are the simple steps to have TFS setup using basic configuration (i.e. everything installed as shown belowJ)

clip_image002

Once the product has installed and you get a successful “Setup is complete” dialog, finish the installation and you will see a TFS configuration wizard. First let us configure Team Foundation Application Server and then configure the Team Build service as shown below:

clip_image004

The TFS Basic install is sufficient as it is the simplest setup option and honestly it does most of the stuff that I need. Honestly in my opinion it is so many times better than TFS 2008 which was much more complicated to set up. For nearly all of the screens just simply keep clicking next and eventually the set up wizard will finish and hopefully you will agree with me that this setup is indeed a breeze.

Once the server configuration is complete, start the wizard for to Configure Team Foundation Build Service and it will come up with a Welcome Screen below:

clip_image006

Again, click Next for each page and accept the defaults, before even you know you will have a functional TFS server ready to go. I know that the above explanation will sound like a joke but really TFS 2010 setup is as simple as that and it is difficult to complicate it unless you really require all the bells and whistles. I did have a loaded Microsoft software box but if you don’t then there might be some minor pre-requisites required but I am sure the setup wizard will let you know that J

Glitch: Now there is one glitch in this entire set up still which I need to call out for you. When you build your web projects, you need the Team Build service to have all the .targets files your projects needs. The TFS installation I showed above does not include all the targets files that comes with Visual Studio 2010. To get the necessary files on your machines, install Visual Studio on the same machine as your TFS server so your projects can build successfully. Now that certainly does not sound very nice so the alternate back door option is to go to %Program Files (x86)%\MSBuild\Microsoft\VisualStudio\v10.0 on your Visual Studio IDE box and copy the target files on your Team Build Server at the similar path. For Web deployment you will most likely only need “Web” and “WebApplications” folder but there is nothing wrong with having all the tasks and targets there just in case you need them later.

Step 2: Connecting to your TFS server from Visual Studio and getting your project into source control

On the home screen of VS 2010 you now have an option to Connect to Team Foundation Server or alternatively you can do so from the “Team” menu within VS too as shown below:

clip_image008

clip_image010

You will then see the “Connect to Team Project” dialog where you point to your TFS Server. If your server isn’t already populated in the server list drop down, you can add it clicking the “Servers…” button:

clip_image012

Once you are connected, you need to create a new Team Project from the File menu:

clip_image014

Give your team project a name and click through the wizard to create your Team Project and finish the wizard. Once your team project is created, you are ready to get your app into the source code control.

If you need further help in setting up your source code control and build server then check out the links below:

· TFS 2010 Installation Guide

· Using Version Control with TFS 2010

· Understanding basic Build with TFS 2010

Step 3: Get your app running and checked into TFS Source Code Control

Well you know how to get your app up and running so I will not dive into that J but just for reference of this walkthrough below the is app I am using. I created this Web App for TechEd US 2010 in New Orleans using MVC Music store sample on CodePlex. (You can watch the TechEd US 2010 video here) As you can see in the sample below it is working on my localhost.

clip_image016

The site is also checked into my TFS source code control as shown below:

clip_image018

To check your application to Source Code Control you simply need to right click it and the menu options will guide you from there.

Step 4: Connect to TFS using Team Explorer

On VS 2010 Team Explorer you will find a button on the top right which will allow you to connect to a team project. When you click the button and select your Team project your Team should similar to what I have below:

clip_image019

Step 5: Create a new Build Definition

A build definition instructs TFS on how to trigger the build. In this case we want deployment to accompany the Build too so we will create a new Build Definition and configure it accordingly. For that right click on the “Builds” node of the Team Project and click “New Build Definition”

At this point you will see the below dialog where you can name your build definition appropriately.

clip_image020

Step 6: Configure your Trigger in TFS 2010 Build Definition

Trigger configuration informs Team Build on when to fire a build there are several options as shown below and I will explain them at high level for you to be able to make the right call

clip_image022

· Manual – As the name suggests this mode allows the Build to be triggered manually as you desire, for demo purposes I am going to use this but ideally you want to explore other options also to determine what works best for you.

· Continuous Integration – This is classic celebrated CI model where every check in into the source code control will cause a build and hence resultant deployment that we would configure.

· Rolling Builds - Sometimes when working in massive teams CI can be disruptive as there are several check ins happening every other hour. In that case you can inform your dev team that there will be a build happening every X minutes and they should plan for that. During end game period of the project this configuration may help to have routine quick builds coming out.

· Gated Check-Ins - This was one of the highly requested features for teams who did not want any broken builds due to bad check-ins. This will ensure that only check-ins which merge & build successfully.

· Scheduled Builds – As name suggests you can also have builds coming out during regular times every day. This is the model which is used by larger VS and .NET teams in general, we too get our builds created on a nightly basis. The funny part is that I do not think that VS & .NET build configuration is as easy as TFS 2010 makes it for everyone else J

Step 7: Configure your Workspace which needs to be built

This is where you specify what you want to build. As shown below I have configured my Project folder as the build target.

clip_image024

Step 8: Provide Drop Location where you want your builds to be dropped

This is relatively a simple step for creating a UNC folder with correct folder permissions so that your TFS build (which typically runs under NETWORK SERVICE) has correct permissions to write to build output path. My setting looks as below:

clip_image025

Step 9: Setup the Retention Policy

Retention Policy simply informs how to save the builds in the drop folder mentioned above. I did not modify mine so it looks as below, although you might want to change these settings based on the disk space that you available:

clip_image027

Step 10: Configuring the Deployment Process

For this you have to go to the “Process” tab which looks as below:

clip_image029

Most of the items in these are self explanatory but I want to spend some time explaining a few which matter in our case:

· Automated Tests – TFS allows you to run the tests in Tests.dll automatically during each build so if you would like to have some unit tests run during build and deployment then this is a great place to mention that. There is also a flag to stop running the tests in the grid which you can set if you do not want to disturb your configuration of this property.

· MSBuild Arguments - This is the location where you need to specific the hooks to mention that you want to trigger deployment as part of the build.

o Web Packaging – For Web Packaging the argument you want to specify is simply:

/p:DeployOnBuild=True;

The above property is going to tell the Web Publishing Pipeline (WPP) to engage after the build is successful. At the default target which executes is Packaging you should not need to provide any other properties.

o Web Publishing – For Web Publishing the arguments you want to specify are:

/p:DeployOnBuild=True /p:DeployTarget=MsDeployPublish /p:CreatePackageOnPublish=True /p:MSDeployPublishMethod=InProc /p:MSDeployServiceUrl=localhost /p:DeployIisAppPath="Default Web Site/NewOrleansJazz" /p:UserName=domain\user /p:Password=myPassword

In this case because we want publishing with Web Deploy to happen we provide /p:DeployTarget value to be MsDeployPublish.

/p:CreatePackageOnPublish allows you to create a package before publishing, it will help you keep an archive of what you published on your local drops folder. Although do note that It will certainly slow down the deployment and eat your disk space so choose it as you see fit.

/p:MsDeployServiceUrl tells the WPP where the project needs to be published to. In the beginning of this post I had mentioned that you need to set up the remote Web Server for Publish, this is the place where it finally gets used. The URL format is typically https://ServerName:8172/MsDeploy.axd. As I am using localhost as my build as well as test server I do not need to provide the full URL (i.e. VS 2010 will complete it as needed) but since your test server is going to be different than build server in real world you will have to provide full URL.

[UPDATE: It was brought to my attention that I had missed a detail in this post which is certainly worth clarifying.  If you are using the Service URL by setting up the server as explained above then you will have to change MSDeployPublishMethod from InProc to WMSVC so the property should become /p:MSDeployPublishMethod=InProc  to /p:MSDeployPublishMethod=WMSVC  Note that if you are publishing to localhost VS can use Web Deploy APIs directly within the same process of VS hence I was using InProc as my option.  If you are publishing to a different server then InProc will not work and give you errors so please make the above change.  Apologies for missing this detail earlier.]

/p:DeployIisAppPath tells the publishing system the IIS Site Name/App Name that you want to publish to. E.g. Default Web Site/MVCMusicStore

/p:UserName=domain\user is the actual User Name which has access to the remote Web Server on which you set up the Web Deploy Publishing

/p:Password=myPassword is the actual Password for the User Name above

NOTE: Do note that the sample here can only publish to IIS 7 (Win2k8 and above), if you are running IIS6 or lower (i.e. Win2k3/ Win2k) then you need to follow slightly different process. Please drop a comment here and I will write a follow up post on that.

o File Copying – This will allow you to simply to a xCopy deployment without needing to setup any remote service

/p:DeployOnBuild=true /p:DeployTarget=PipelinePreDeployCopyAllFilesToOneFolder /p:_PackageTempRootDir=\\BuildServer\BuildDrops\MVCMusicStore /p:AutoParameterizationWebConfigConnectionStrings=false

/p:_PackageTempRootDir allows you to specify the remote server location on which you want xCopy to happen. Again the remote location will need permission to be writable by Team Build Agent which is running the deployment

/p:AutoParameterizationWebConfigConnectionStrings=false essentially tells WPP to not parameterize the Web.Config file since doing so will introduce replicable tokens within Web.Config which are used during Packaging & Publishing.

NOTE: File Copying was honestly never designed out of the box to be used from Team Build in such fashion but some people have been interested in using Web.Config Transformation during xCopy and hence I thought it was worthwhile mentioning this in the blog.

PS: Using properties which begin with underscore “_” is not typically recommended as they are considered private MSBuild variables by convention but in this case it is relatively easy way to accomplish the xCopy solution. Even in future versions of VS if this property changes I am hopeful there will be alternate/easier way to do this. In general if you can set up the Publishing on your web server using Web Deploy I think it will yield you longer term advantages and I think it is a worthwhile endeavor to take.

· Projects To Build - When you have only one web application and class libraries then it is easier to just have the Project (CSProj or VBProj) to build as shown in my example above, but if you have bunch of projects which all need to built then you might have to go with Solution Build option (.SLN).

Deployment for Web Apps is feasible at both Solution as well as Project build level although when it comes to Solution Build then you might want to make sure that the properties you are passing at Solution level will apply to all the projects in the solution which might not always the outcome you desire. In that situation all these properties can be set within the .csproj or .vbproj files too. You can do that by unloading your project file and in the top <PropertyGroup> section just add above properties as you like:

For e.g /p:DeployOnBuild=True can be added as <DeployOnBuild>True</DeployOnBuild>

Step 11: Trigger your Build Definition

Now that you have everything configured you can right click on the Build Definition and hit “Queue New Build”.. That will show you a dialog which you can simply hit OK on and you should soon get your Build ready and the site deployed as shown in my case below:

clip_image031

After a while when you check into the Completed section of the build you should see your new build lined up.

clip_image033

On inspecting the IIS and SQL Server you can see my sites & DBs are also deployed.

clip_image034 clip_image035

Finally on running the application it runs great too:

clip_image037

This was actually a combination of setting up my DB deployment settings too, to learn more about configuring your deployment in the right way check out TOC on Web deployment.

PS: If you get an error on TFS like below:

TF215097: An error occurred while initializing a build for build definition \TechEd-US-2010\MvcMusicStore: There was no endpoint listening at http://MyServer:9191/Build/v3.0/Services/Controller/1 that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.

Then most likely you do not have your Build Service running, you can enable it by going to Start à All Programs à Team Foundation Administration Console à Build Configuration.

Conclusion

Hopefully this will get you going with your automated web deployments. Please write back if you feel anything is missing or if you have any other questions. If you have questions like how would you configure what gets deployed, how to set up DB deployment, how to change web.config etc etc we have tons of articles on how to customize your deployment. You can look at a whole list of them at Overview of Web Deployment

Hope this helps

Vishal

Friday, June 18, 2010

Parameterization vs. Web.Config Transformation

I was recently asked about being able to change values of different variables like ConnectionStrings, Installation physical directory, app Settings etc during install time rather than build time, so I thought it might be worth while to de-mystify the concepts around Web.Config Transforms and Parameterization…

Web.Config Transformation

Geeks say Web.Config Transformation is a great feature of Web Deploy (aka MsDeploy), well the first part about being a great feature is true :-) but it is important to note that Web.Config Transformation is not a Web Deploy feature but it instead is a VS 2010 only feature.  Web.Config Transformation is connected with Build configuration of MSBuild/VS/Team Build etc…  Its XML transformation engine is wrapped in MSBuild and has a UI around in VS 2010 which yeilds following benefits:

If you are building a deployment web package (.zip) and know which environment you are building for then web.config transformation is great.  This is the category where many of us fall coz we build for a release environment and need the right config file to go in that deployment package.  For that matter many people are just fine creating web packages for the correct environment they are deploying to…

Now for others who want to be able to build just once and deploy to both test as well as staging/release environment then an embedded web.config file for one environment may not work.  For this scenario there is parameterization.

Parameterization

Parameterization, unlike Web.Config Transform is Web Deploy (aka MsDeploy) only feature, which means that it will not work in non-Web projects or when you are using other protocols like FTP/FTPS etc.  Parameterization from Web Deploy standpoint is a 2 step process

  1. Declare Parameters: You create a Parameters.xml file and pass it to Web Deploy while creating the package…  In this file you need to indicate what file you want to parameterize  (e.g. web.config), what variable inside the file needs to be parameterized (e.g. connectionString) and what would be the default value of the variable (e.g. release connectionString)… Using Parameters.xml file, Web Deploy will create an internal meta data file within your .zip package which guides Web Deploy to know what “Questions” to ask the person who is installing the .zip package… 
  2. Set Parameters: When user is about to install the web package the value of the Parameters can be provided to Web Deploy via several means.  In case you are using IIS Manager to install the package then the IIS Manager UI will automatically show the Parameters with filled in default values.  If you are using Web Deploy command line to install the package then you can provide a setParameters.xml file to the commandline (in case of VS 2010 generated deploy.cmd file just having setParameters.xml file in same folder as the .cmd and .zip file is sufficient).  The setParameters.xml file is a very simple name-value pair file in which you can provide the value of the parameter adjacent to its name.

In one of the future posts I will write more about how to use Parameterization for some canonical deployment scenarios, but hopefully this will lay the foundation of how to differentiate between build time transforms from install time parameters.

Conclusion

If you can know your environment settings during build time use Web.Config transformation. 

If you would want to create deployment package only once and then enter the settings during install time then use Parameters.xml

VS 2010 actually uses a combination of Parameters and Web.Config transforms to provide you with a seamless experience (i.e. connectionStrings, IIS Application Name etc are already parameterized by default) so for most common scenarios you would hopefully not have to delve into understanding all the details but if you have any questions then of course feel free to ask here or via email…

Thanks

Vishal

Tuesday, May 18, 2010

Applying XDT magic to App.Config

For several weeks now people have been asking to be able to use the XML Document Transform (XDT) with App.Config files similar to what is available with Web.Config files in VS 2010…
In all honesty there is no official/supported  implementation of XDT for any other project type than Web Application Projects but the good news is that the basis of Web.Config Transformation resides in Web Publishing Pipeline (WPP) which are set of extensible tasks and targets hooked up to provide a great deployment story for Web Applications…
Today, Ming (our senior dev on Visual Studio) and I decided to get together to give some love to App.Config file too… The below implementation is a crude way of getting XDT working into other project types within VS 2010… In a way, I would say it is a big solution for a smaller problem but the idea here is to get people unblocked and show the kind of things that WPP is capable of doing… 
If by now everything is sounding foreign then please check out the articles:

  • Web.Config Transformation
  • VS 2010 Snippets for Web.Config Transformations
  • Web.Config Transforms (XDTs) for any XML files in your web projects
    Goals
    • Being able to use XDT syntax for App.Config files similar to what you can use with Web.Debug.Config and Web.Release.Config…
    • Being able to use this in an automated fashion in build environments like Team Build…
    • Reduce the concept count and make it as simple as possible (without digging deep into optimization & performance)…
  • Please take a look at Visual Studio extension which allows you to do this without the manual workarounds below:
  •  http://visualstudiogallery.msdn.microsoft.com/69023d00-a4f9-4a34-a6cd-7e854ba318b5

    Step by Step Instructions

    The example I am using below should be hopefully super simple that you can follow along without any prep work… All you need is VS 2010 which has “Visual Web Developer” components installed…

    Step 1 Create a new Windows Forms Application in VS 2010

    Step 2 Add App.Config file to the project…

    Add simple test settings to App.Config file as shown below:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <appSettings>
        <add key="author" value="Vishal Joshi"/>    
      </appSettings>
    </configuration>




    Step 3 Add App.Debug.Config file to the project, I would recommend using the same App.Config file adding mechanism as shown below




    app.debug.config



    Step 4 Modify the content of App.Debug.Config as shown below:



    <?xml version="1.0"?>
    
    <!-- For more information on using App.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 -->
    
    <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
      <appSettings>
        <add key="article" value="XDT Magic for App.Config Files" xdt:Transform="Insert"/>
      </appSettings>
    </configuration>





    The key things to note above are:





    • There is a XDT namespace declaration which allows XDT engine to recognize the Transform/Locator syntax in the file


    • There is a new node being inserted into the config file using the syntax xdt:Transform=”Insert”




    Step 5 Save the edited files and unload the project frin VS 2010 Solution Explorer using the right click command as shown below:



    unload project




    Step 6 Edit the .csproj/.vbproj file to make App.Debug.Config file to be dependent on App.Config file as shown in the syntax below:




        <Content Include="App.config" />
        <Content Include="App.Debug.Config" >
          <DependentUpon>App.Config</DependentUpon>
        </Content>





    The key things to note above are:





    • By default the build action of App.Config and App.Debug.Config file will be “ None”… It needs to be changed to “Content”… This is a tiny pre-requisite for WPP but if you encounter any issues because of this then we can dig the work around…


    • DependentUpon node will make your App.Debug.Config appear as a node under your App.Config file similar to the way Web.Debug.Config and Web.Release.Config files appear under Web.Config file…


    • In VB Projects nested files are hidden so you might need to unhide these by clicking the icon on the solution explorer…




    Step 7 Change the ProjectConfigFileName property within your .csproj/.vbproj file



    WPP has an inbuilt property called ProjectConfigFileName which is by default set to Web.Config, we need to change this to app.Config which will allow projects like WinForm project not expect web.config files to transform… You can add this property right under ProjectGuid property as shown below:



      <PropertyGroup>
        <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
        <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
        <ProductVersion>8.0.30703</ProductVersion>
        <SchemaVersion>2.0</SchemaVersion>
        <ProjectGuid>{2D587604-866B-4675-8587-FA9728EC59D8}</ProjectGuid>
        <ProjectConfigFileName>App.Config</ProjectConfigFileName>




    Step 8 Hook up WPP within your WinForms project by importing the WPP targets.



    You can search for “Import” node in your project file and then simply copy below one line for WPP targets import



      <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets" />





    Step 9 Add a target to copy the transformed App.Config file to your output (BIN) directory




    You can simply copy paste the below code just before your </project> node closes in the .csproj/.vbproj file



      <Target Name="PostTransformAppConfig" AfterTargets="TransformWebConfig">
        <Copy Condition="Exists('$(TransformWebConfigIntermediateLocation)\transformed\App.config')" 
              SourceFiles="$(TransformWebConfigIntermediateLocation)\transformed\App.config" 
              DestinationFiles="$(OutputPath)\WinFormConfigTransform.exe.config" />
        <Copy Condition="Exists('$(TransformWebConfigIntermediateLocation)\transformed\App.config')" 
              SourceFiles="$(TransformWebConfigIntermediateLocation)\transformed\App.config" 
              DestinationFiles="$(OutputPath)\WinFormConfigTransform.vshost.exe.config" />
      </Target>





    The key things to note above are:





    • We hooked up the new PostTransformAppConfig target after TransformWebConfig target… The TransformWebConfig target is the native target in WPP which does any XML transform and will do the actual job of transforming App.Config as well..


    • The location at which the new App.Config file is getting copied is pretty self explanatory but do note that you do want to change “WinFormConfigTransform” to be the name of your own Project…  I just used a project called “WinFormConfigTransform” and hence the DestinationFiles path is named as such…




    Step 10 Run /T:TransformWebConfig task on your Project from MSBuild



    You need to use Visual Studio 2010 Command prompt and type in the below command



    msbuild C:\Vishal\WinFormConfigTransform.csproj /t:TransformWebConfig



    After running the above command if you now check the BIN folder of your project you should see that the Project.exe.Config file is now modified as shown below:



    image 



    NOTE: If you want the App.Config file to be Transformed after every build in your Visual Studio IDE (this will take some perf away but may not even be noticeable) then you can change Step 9 code to be as below:



    <Target Name="PostTransformAppConfig" AfterTargets="Build">
        <CallTarget Targets="TransformWebConfig"/>
        <Copy Condition="Exists('$(TransformWebConfigIntermediateLocation)\transformed\App.config')" 
              SourceFiles="$(TransformWebConfigIntermediateLocation)\transformed\App.config" 
              DestinationFiles="$(OutputPath)\WinFormConfigTransform.exe.config" />
        <Copy Condition="Exists('$(TransformWebConfigIntermediateLocation)\transformed\App.config')" 
              SourceFiles="$(TransformWebConfigIntermediateLocation)\transformed\App.config" 
              DestinationFiles="$(OutputPath)\WinFormConfigTransform.vshost.exe.config" />
      </Target>



    The only key difference above is that I made the new target to be called after “Build” and in the new target I made a call to “TransformWebConfig” target to ensure the transform happens before we try to copy the transformed app.config file to their final location…




    With the above change now when you build in IDE then the new transformed App.Config will be copied to your output directory…



    With the above 10 steps you should now be able to Transform your App.config just like the way you do Web.Config files in VS 2010



    -Vishal



    PS:  Whenever you make changes to your project file (like above) you make your project susceptible to data loss during upgrade to future versions of VS as next versions of VS will not know all the fancy code you put in the files, but such risks are part of the game to get all the fancy toys working :-)

    Sunday, May 02, 2010

    Xml Document Transforms (XDT) for any XML file in your project

    There have been several requests floating around to be able to use XDTs (the technology behind Web.Debug.Config/Web.Release.Config) with other XML files within the project…  To make that feasible I wrote a XmlDocumentTransform.targets  file which can generically transform any XML file using the standard Web.Config Transformation syntax introduced with VS 2010…

    Learn more about XDT & Web.Config Transformation here…

    Now to get started first download XmlDocumentTransform.targets file from my Skydive…

    Follow the below simple steps to get transformation working for any well formed XML file in your project…

    • Step 1: Save the downloaded XmlDocumentTransform.targets to %ProgramFiles%\MSBuild\Microsoft\VisualStudio\v10.0\Web\XmlDocumentTransform.targets

    image

    NOTE: I would highly encourage you to make a copy of the Microsoft.WebApplication.targets file as backup before you do Step 2 below, as if this file is modified incorrectly then your VS 2010 instances might start showing funny problems which will be virtually impossible to debug and the only option left with you will be to repair/uninstall-install VS 2010… (i.e. proceed at your own risk :-))

    •  Step 2: Put following line of code in Microsoft.WebApplication.targets file just before closing of the Project node i.e. before </Project>...  
      <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\XmlDocumentTransform.targets" Condition="Exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\XmlDocumentTransform.targets')" />
      The Microsoft.WebApplication.targets file is located at %ProgramFiles%\MSBuild\Microsoft\VisualStudio\v10.0\WebApplications... 

    image  
    NOTE: Changing the above targets file will allow you to use this functionality with all the Web Application Projects (WAPs), if you just want to change this for the current project then you can put the same Import node in .csproj or .vbproj as well...  If you use per project model then you can also check in this file into source code control and have your team use it seamlessly…

    • Step 3: Open your .csproj/vbproj file and insert the below property in <PropertyGroup> section  <AllXmlsToTransform>Settings.xml;app.config</AllXmlsToTransform>

    image

     NOTE: The Settings.xml or app.config can be replaced with the name of Xml files you want to transform…

    • Step 4: Insert <OnAfterTransformWebConfig>TransformXml;</OnAfterTransformWebConfig> similar to #3 above but do not modify the TransformXml; text here…  This is the actual hook which ties in your project to this generic XDT system...  After making the Step 3 & Step 4 changes your project file should have below content…

    image

    • Step 5: Create Setting.Debug.Xml or similar files and put XDT syntax in them... You need to make sure in the .csproj/.vbproj file of yours you have the DependentUpon property is set like the example below:
          <Content Include="Configuration\Settings.xml" />
          <Content Include="Configuration\Settings.Debug.xml">
            <DependentUpon>Configuration\Settings.xml</DependentUpon>
          </Content>
          <Content Include="Configuration\Settings.Release.xml">
            <DependentUpon>Configuration\Settings.xml</DependentUpon>
          </Content>

    image

    NOTE: The above will allow your solution to look pretty, i.e. just like web.debug.config and web.release.config files show nested under web.config, your *.$(configuration).* files will show nested under your parent file too…

    With the above 5 steps you are all set to use XDT with any of the deployment models covered in the Overview of Web Deployment Post…  In a way above steps harness the power of Web Publishing Pipeline (WPP) extensibility model and you can do several other extensions like above if you are familiar with MsBuild sytax…

    SAMPLE:   The remainder of the post is just showing you the steps to test whether the changes you made worked or not (i.e. the remaining half of the post is just playing with what you already accomplished in the first half)… :-)

    • To test the above target file I created the below MVC 2.0 project structure:

    image

    • Once you put DependentUpon node in your project file you will have to click the  “Show All Files” icon on the solution explorer for VB Projects to see Settings.Debug.Xml
    • My Settings.xml file looked as below:

    image

    • My Settings.Debug.xml file looked as below:

    image

    • To test out I tried simple “file system” publish (Right click on project and say Publish)… The new WAP Publish dialog for me looked as below:

    image

    • After publishing my C:\TestPublish folder looked as below:

    image

    • Note that Settings.Debug.xml was removed from my final publish location as it is not required for my web to function and the content of Settings.xml file were transformed and looked as below:

    image

    TeamBuild/Commandline Approach: You can also use your new transformations from TeamBuild/MsBuild by using the below command (from VS 2010 Command prompt if you are trying locally):

    MsBuild MyXDTTestProject.csproj /t:TransformXml

    The output of the command line transform should look as below:

    image

    As specified above your transformed XML will be stored in obj\$(configuration)\Settings.xml… 

    As such feel free to open the XmlDocumentTransform.targets file which you download, I have tried to put as much comments as I could to make it readable…  If you go through it I am sure you will be able to do many other cool things out of it…

    -Vishal

    Monday, April 26, 2010

    Xml Document Transform (XDT) Snippets for VS 2010

    During my PDC talk I had shown some of the snippets that can come handy while using Web.Config Transformations…  This post is intended to share the XDT snippets and instructions on how to install them to use them with VS 2010…

    image

    • After this the XDT snippets will be available for you to use within any XML file within VS 2010…

    To know how to use XDTs for Web.Config file please check out the post about Web.Config Transformations

    Few interesting points about Transforms & Locators which are worth noting to do pretty powerful stuff with your XML are:

    • Transforms  - Transforms act on a XML node i.e. from XDT engine standpoint the node on which a transform is found is plucked out of the document and passed as a node to the Transform itself (e.g. “SetAttributes” Transform)… The Transform class internally implements the logic of modifying the node with its own special logic (i.e. setting attributes in case of “SetAttributes” Transform) and returns back the node to the engine…  The XDT engine then replaces the new node into the document…  The engine also passes the handle of the parent node to the transform which the transform can then play around with (e.g. “Insert” Transform receives a new node as well as the parent node and has the DOM code of inserting the new node under the parent…)

    image

    • Locators – XDT usually traverses through the XML document and constructs the XPath all along e.g. when it hits the add node under connectionStrings in web.config it has already constructed the XPath (/configuration/connectionString/add)…  Locators help with narrowing down the XPath so that the correct node can be picked up… Check out the example below:
       <connectionStrings>
    <add name="1stDB"
    connectionString="Data Source=Server1;Initial Catalog=DB1;Integrated Security=True"
    xdt:Transform="SetAttributes" />
    <add name="2ndDB"
    connectionString="Data Source=Server2;Initial Catalog=DB2;Integrated Security=True"
    xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
    </connectionStrings>




    Based on the standard logic of XPath traversing XDT will always pick up the first “add” node i.e. one with 1stDB in the example below… That may not be always desirable…  In XDT we could have implemented the logic to do special things for appSettings & connectionStrings but then that would have made XDT specific to web.config instead we implemented Locators which now allows XDT to be general purposes XML transformation engine…  In the above example if we use a Locator called xdt:Locator=”Match(name)” on the 2ndDB then as soon as the XDT engine encouters a locator it calls the class implementing it (i.e. “Match” and allows it to play with the XPath that is being generated… In this case the match locator will help construct the XPath as /configuration/connectionString/add[@name=’2ndDB’]



    xdt:locator



    The high level takeaway here is that when you play around with the snippets for XDT keep the above concepts for Transforms & Locators in mind and with the quick snippet explanations of each transforms and locators you should be able to very easily use all of them… If you encounter any issues plz feel free to reach out…



    Thanks!!



    -Vishal