Home
About
Contact
Monday, August 16, 2010

In Part 1 I hadn’t decided if I was going to use Web Deploy as the base of this blog series or the PowerShell scripts I already had in production. I decided to give Web Deploy a chance. In the end I didn’t regret it, but I must admit it was not straight forward. Hopefully this post will make it a breeze for you :-)

Web Deploy With VS 2010 and TFS 2010

VS 2010 and TFS 2010 now comes with Web Deploy integration and works great for low to medium complex web apps. When I tried it out with my requirements I did not manage to get my solution to work so I reverted back to the command line version.

The documentation for this topic is also sparse, and it looks/feels unfinished. Here’s some resources if you’re going down that road:

The Web Deploy MSBuild schema: C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web

The official doc: http://msdn.microsoft.com/en-us/library/dd394698.aspx

Web Deploy @PDC: http://www.microsoftpdc.com/2009/FT56

FAQ: http://blogs.msdn.com/b/aspnetue/archive/2010/03/05/automated-deployment-in-asp-net-4-frequently-asked-questions.aspx

MSBuild Web Deploy arguments + more resources: http://weblogs.asp.net/jdanforth/archive/2010/04/24/package-and-publish-web-sites-with-tfs-2010-build-server.aspx

THE commands

The two commands below solves all the requirements I listed in my previous post. I spent a great deal of time learning and studying Web Deploy in order to come up with this, so I hope you find it useful. It might not look too hard now, but nothing is when you have the solution in front of you :-) I’m always open for better ways if you find one though. If I could ask the Web Deploy team for a new feature, it would be to make the two commands below really simple.

The rest of this post will discuss these commands in detail. Text in blue can be replaced with your own values.

Create package:

msdeploy.exe 
	-verb:sync 
	-source:manifest=PackageManifest.xml
	-dest:package=Package.zip,encryptPassword="certificatePassword" 
	-enableLink:AppPoolExtension
	-disableLink:CertificateExtension 
	-disableLink:ContentExtension 
	-replace:objectName=httpCert,targetAttributeName=hash,replace=08bf3e051bd10cd8d89ac1a3ac431887886ed343
	-replace:objectName=logFile,targetAttributeName=directory,replace=C:\Web\Logs 
	-replace:objectName=virtualDirectory,targetAttributeName=physicalPath,match="C:\\WebDeployTemplateWebSites",replace="C:\Web" 
	-declareParam:name=HttpsBinding,kind=DestinationBinding,scope=webSiteName,match=.*:443: 
	-declareParam:name=HttpBinding,kind=DestinationBinding,scope=webSiteName,match=.*:80:
	-declareParam:name=AppPoolUsername,kind=DeploymentObjectAttribute,scope=processModel,match=processModel/@userName 
	-declareParam:name=AppPoolPassword,kind=DeploymentObjectAttribute,scope=processModel,match=processModel/@password

Install package:

msdeploy.exe 
	-verb:sync 
	-source:package=Package.zip,encryptPassword="certificatePassword" 
	-dest:manifest=InstallManifest.xml,computerName=FQDN,username="domain\user",password="domainUserPassword" 
	-setParam:name=HttpsBinding,value=10.0.0.21:443: 
	-setParam:name=HttpBinding,value=10.0.0.21:80:
	-setParam:name=AppPoolUsername,value=MyDomain\AppPoolServiceAccount
	-setParam:name=AppPoolPassword,value=MySecureAppPoolPassword

Note that the above commands are one-liners. I only structured them the way I did to make them readable.

Complex

Web Deploy was built for the purpose of deploying web applications, so at first it looked like the perfect solution. However, I soon realized I had to study it in great detail to make it do what I wanted. I’m talking days not hours. Time I was not eager to spend to replace something already working or just for the sake of this blog post (sorry guys :-)). The reason for not giving up on it entirely was because Web Deploy had the potential to simplify/replace my scripts, have fewer moving parts, and make the total solution easier to maintain.

Around the same time as I published Part 1 I tweeted my concern about Web Deploy’s complexity and the @wdeploy team contacted me. I sent them a long email describing my concerns and they promised to do “creative things in the future” to make it less complex. I’ve been in contact several times after that and they are very responsive and eager to get feedback on the product. I’m personally looking forward to see (and maybe help influence) how this product will evolve.

Web Deploy Command Options

Before diving into the inner workings of these commands, we need to know a bit more about the tool. Web Deploy have a lot of functionality and is extremely powerful. Here’s the command line syntax:

	msdeploy.exe -verb:<verbName>
	-source:<provider>[=<pathToProviderObject>
		[,<providerSetting>=<providerSettingValue>]]
	[-dest:<provider>[=<pathToProviderObject>
        	         [,<providerSetting>=<providerSettingValue>]]
	]
	[-<MSDeployOperationSetting> ...]

Doesn’t look too scary right? There is more to it though…

Verbs
The following verbs exist:

  • delete
  • dump
  • getDependencies
  • getParameters
  • getSystemInfo
  • sync

Providers
Let’s look at which providers it has:

These are of course only the built-in providers, then you can create your own or use 3rd party ones if you like. A quick scan through this list shows that it does a lot more that just web stuff, like COM objects, registry settings, certificates, gac, databases.. the lot.

Provider Settings
The providers again have a set of common provider settings:

  • authType
  • computerName
  • encryptPassword
  • getCredentials
  • ignoreErrors
  • includeAcls
  • password
  • storeCredentials
  • tempAgent
  • userName
  • wmsvc

MSDeployOperationSetting
From the documentation:

Web Deploy operation settings are non-provider specific command-line flags. They modify all of a Web Deploy operation.

  • allowUntrusted
  • declareParam
  • declareParamFile
  • dest
  • disableLink
  • disableRule
  • disableSkipDirective
  • enableLink
  • enableRule
  • enableSkipDirective
  • postSync
  • preSync
  • removeParam
  • replace
  • retryAttempts
  • retryInterval
  • setParam
  • setParamFile
  • showSecure
  • skip
  • source
  • useCheckSum
  • verb
  • verbose
  • whatif
  • xml
  • xpath

Manifest Provider
We now have an overview of the command line syntax of the tool, but there are a few other important aspects. The first one being the manifest provider. Most likely you want to use more than one provider in your command, and that’s exactly what this provider does. Here’s an example from the documentation:

<sitemanifest>
   <appHostConfig path="mySite" />
   <gacAssembly path="System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
   <comObject path="Microsoft.ApplicationHost.AdminManager" />
   <contentPath path="c:\source" />
   <regKey path="HKLM\Software\ODBC" />
</sitemanifest>

I would actually preferred having these on the command line instead. When I trigger my commands from a build, I’m inserting variables into the command anyways and I would be better of with the ONE command and not have to maintain the xml files as well. Actually I would like to have both options. In the command I would suggest something like this (which would adhere to the existing conventions):

-source:appHostConfig=mySite,gacAssembly=System.Web…,[…]=[…]

Link Extensions
Another one is the concept of link extensions, which can be enabled/disabled by using the enableLink and disableLink operations. One example drawn from the documentation is:

…if you specify -disableLink:ContentExtension on the command line, you can prevent content from being included in a sync operation. This enables you to synchronize two Web servers without moving any content.

Web Deploy Rules
Web Deploy rules exists to disable or enable built-in or custom rules (using e.g. the enableRule and disableRule operations) for the sync verb. This is however (naturally) only true if the isDefault attribute is set to true in the rule definitions. See here to find the built-in rules. By creating the file Msdeploy.exe.configsettings in %program files%\IIS\Microsoft Web Deploy folder, you can add custom rules.

Packages and Archives
From the docs:

The Web Deploy package and archiveDir features let you create a snapshot backup of your Web site or Web server into a .zip file or archive directory. In addition, the parameterization and manifest features let you customize the archive or package that you create. You can then use your package files to deploy Web sites and Web servers to other computers or computer locations.

What’s wrong?

That’s a lot of stuff to consume! In order to effectively use this tool for deployment, you have to learn most of these verbs, providers and operations, figure out how they work and how you can take advantage of them.

This is (in my opinion) what Greg Young have been talking about and expressed in the NDC Magazine article Failure (well worth the read), where the intent is lost in the system and the user is forced to “reverse engineer” it to make sense of it all.

I’m fully aware of the endless amount of user scenarios that exists, and I don’t expect the Web Deploy team to cover them all, but the most common ones would be nice. Like the one I’m showing in this post I would think would be quite common for auto deployment scenarios. The advanced configuration could still be available for the not-so-common scenarios. Instead I’m “forced” to spend a lot of time learning the inner workings of a complicated tool, which in the end create a lot of value. How valuable wouldn’t it be if I didn’t have to invest so much time in learning the tool?

I’m also aware of the new TFS 2010 integration that exists, which simplifies many of these tasks, but that solution lacks documentation and the advanced options are hard to get at.

Setting up Web Deploy for remote access

To be able to access a server remotely, Web Deploy must be given access to the server. Several options are available, but I’ll focus on the Web Deployment Agent Service, which requires administrator privileges to use.

The Agent Service requires Web Deploy to be installed on the target server. You can find the detailed installation instructions here: http://technet.microsoft.com/en-us/library/dd569030(WS.10).aspx

Basic Usage

Let’s look at some vanilla examples for deploying web stuff remotely:

msdeploy
  -verb:sync
  -source:contentpath=c:\data,
  -dest:contentpath=c:\data,
      computerName=Server2,
      username=admin,
      password=pass

This copies your local C:\data directory to the server Server2, and provide a username and password to get access to the remote server. This is done by using the sync verb and the contentpath provider. So we can push files, which is nice cause we don’t have to use FTP, BITS or similar.

Deployment Requirements 

We want to do a lot more than just copy files. Here’s a list extracted from my previous post of what I want to deploy to remote servers:

  • File content
  • Virtual Directories and Applications settings
  • AppPools settings
  • Certificates
  • Bindings
  • Log location settings
  • Virtual Directory file location settings

Packaging structure

My commands can be used to produce one package per web site multiplied by the number of environments you have (e.g. Dev, Test and Prod). So if you have 4 web sites and 3 environments, you create 12 packages.

To better understand why this is, here’s a list of the settings that are specific for each environment and common across all servers in one specific environment:

  • File content
  • SSL Certificate password
  • Certificate hash/thumbprint
  • Web site log directory location
  • Virtual directory root locations

For server specific differences we create the package so that it accepts parameters for:

  • User and password for the service account under which the worker process of the Application Pools runs
  • The https binding (if used)
  • The http binding (if used)

If we did not define the last three parameters, we would have to multiply the packages with the amount of servers in the different environments as well. 4 web sites, 3 environments and 2 servers in each environment = 24 packages. You don’t want to go there…

Another option would be to define all possible changes as parameters, leaving you with only one package. I tried that. I could not figure out how to accomplish all of these using params, so I analyzed what I needed and used a little of both. It works, but could be better.

As an example of the above, a package for the web site blog.torresdal.net could be created for e.g. Dev with these settings:

  • File content = E:\MyBuildOutput\blog.torresdal.net
  • Certificate password = MySecureSSLPassword
  • Certificate hash=08bf3e051bd10cd8d89ac1a3ac431887886ed343
  • Web site log dir = E:\Logs\blog.torresdal.net
  • Virtual Directory locations = E:\Web

…and used these parameters when deploying:

  • Username for AppPool = MyDomain\AppPoolServiceAccount
  • Password for AppPool = MySecureAppPoolPassword
  • Https binding = 10.0.0.21:443:
  • Http binding = 10.0.0.21:80:

Notes on Application Pool

Note on bindings: You have to use either http or https or both. If you want to use hostname you could do: *:80:blog.torresdal.net
Note that host names are not supported on SSL in IIS 7, even though it’s technically possible to do.

Note on the service account for the application pool: On Windows Server 2008, IIS support Application Pool Identities. These are Windows virtual accounts that are assigned to the application pool effectively isolating it from other services. If you want to use these, then you don’t have to declare the parameters for the app pool identities as long as your source is using App Pool Id’s.

Dissecting The Create Package Command

I believe you now have an idea of what the commands above do, but lets pull it apart and describe each piece by itself.

The package manifest file
First we’re going to look at the manifest file which contains all source providers used to create the package:

<sitemanifest>
   <appHostConfig path="blog.torresdal.net" />
   <cert path="my\08bf3e051bd10cd8d89ac1a3ac431887886ed343 " />
   <dirPath path="E:\MyBuildDrop\LatestVersion\Dev\blog.torresdal.net" />
</sitemanifest>

This is the way that Web Deploy allows you to use more than one provider. Here’s a short description of each provider and what it does:

appHostConfig Gets all IIS specific settings from a web site.
cert Gets the certificate with the given thumbprint/hash.
dirPath Gets the content from the given path.

The create Package command
Now lets look at each section of the command:

-verb:sync Tells Web Deploy to do a sync
-source:manifest=PackageManifest.xml Points to the manifest file showed above containing all providers to use as source.
-dest:package=Package.zip,
encryptPassword="certificatePassword"
Use the package provider as destination for creating a package (zip) containing all content and information needed to deploy a package to a server. Since we’re using the cert provider (in the manifest) we need to provide the password to get access to the certificate.
-enableLink:AppPoolExtension I want the application pool to be synced as well.
-disableLink:CertificateExtension The appHostConfig provider include certificate and content by default. I want to control which certificate and what content to include, so I use –disableLink to disable these extensions. That is why I’ve added the cert and dirPath providers in the manifest so that I can be explicit about these.
-disableLink:ContentExtension See previous…
-replace:objectName=httpCert,
targetAttributeName=hash,
replace=08bf3e051bd10cd…
The appHostProvider and the cert provider are unaware of each others actions, so the appHostProvider outputs the thumbprint from the certificate found in IIS. I need to replace the httpCert hash property with the same hash used in the manifest file or else the web site would be bounded to the wrong certificate.
-replace:objectName=logFile,
targetAttributeName=directory,
replace=C:\Web\Logs
I want to replace the IIS log directory to a different path than the IIS I’m exporting from.
-replace:objectName=virtualDirectory,
targetAttributeName=physicalPath,
match="C:\\WebDeployMasterWebSites",
replace="C:\Web"
The web site I’m exporting from reside in C:\WebDeployMasterWebSites\{webSiteName}, and all Virtual Directories are located below this path. I want to control the root path, so I replace it.

Note: This would be a natural candidate for a parameter, but with params you can only replace the complete value, not just part of it.

Here’s a description of the parameter declarations allowing us to pass in params when deployment the package (these are also part of the same command):

-declareParam:name=HttpsBinding,
kind=DestinationBinding,
scope=webSiteName,
match=.*:443:
I want to control the SSL binding for the web site.
-declareParam:name=HttpBinding,
kind=DestinationBinding,
scope=webSiteName,
match=.*:80:
Same as above only for HTTP.
-declareParam:name=AppPoolUsername,
kind=DeploymentObjectAttribute,
scope=processModel,
match=processModel/@userName
I want to set the user name of the account under which the worker process of the Application Pools runs
-declareParam:name=AppPoolPassword,
kind=DeploymentObjectAttribute,
scope=processModel,
match=processModel/@password
Same as above only for the password.

To shorten the above command a tiny bit you can define the parameters in an xml file instead, like this:

<parameters>
   <parameter name="HttpsBinding" description="Web Site Binding for SSL">
      <parameterEntry kind="DestinationBinding" scope="sikker.frende.no" match=".*:443:" />
   </parameter>
   <parameter name="HttpBinding" description="Web Site Binding for http">
      <parameterEntry kind="DestinationBinding" scope="sikker.frende.no" match=".*:443:" />
   </parameter>
   <parameter name="AppPoolUsername" description="Account username for this application pool">
      <parameterEntry kind="DeploymentObjectAttribute" scope="processModel" match="processModel/@userName"/>
   </parameter>
   <parameter name="AppPoolPassword" description="Account password for this application pool">
      <parameterEntry kind="DeploymentObjectAttribute" scope="processModel" match="processModel/@password"/>
   </parameter>
</parameters>

You will then replace the –declareParam operation settings above with this:

-declareParamFile:MyParamFile.xml

However, if you’re going to execute this command from TFS or some other build tool, you’re better off leaving them inside the command. Less moving parts.

Dissecting The Deploy Package Command

We also need a manifest file when installing the package. This is ALMOST identical to the manifest we used when creating the package:

<sitemanifest>
   <appHostConfig path="blog.torresdal.net" />
   <cert path="my\08bf3e051bd10cd8d89ac1a3ac431887886ed343 " />
   <dirPath path="E:\Web" />
</sitemanifest>

The only difference between the two is in the dirPath provider. For the package we used files from E:\MyBuildDrop\LatestVersion\Dev\blog.torresdal.net, but when deploying we PUT files to E:\Web.

The deployment package command
Each section in detail:

-verb:sync Tells Web Deploy to do a sync
-source:package=Package.zip,
encryptPassword="certificatePassword"
Uses the earlier created package as source. Since this package contains a certificate, you need to provide the certificate password in order to get access to it.
-dest:manifest=InstallManifest.xml,
computerName=FQCN,
username="domain\user",
password="domainUserPassword"
Points to the manifest file to use for deployment, and to which server we are deploying to with the username/password.
-setParam:name=HttpsBinding,
value=10.0.0.21:443:
Set the SSL binding for the web site. Using IP 10.0.0.21 on port 443 (SSL).
-setParam:name=HttpBinding,
value=10.0.0.21:80:
Same as above only for HTTP.
-setParam:name=AppPoolUsername,
value=MyDomain\AppPoolServiceAccount
Set the user name for the account under which the worker process of the Application Pools runs
-setParam:name=AppPoolPassword,
value=MySecureAppPoolPassword
Same as above, only for the password

The Build/Deploy Process Using Web Deploy

Here’s the exact same deployment process overview as in my previous post, only now with Web Deploy. As a result the process got two steps shorter :-)

image

What’s Next?

In my next post I’ll either show you how to control the load balancer during deployment or integration with TFS. Both will be covered in the end.

.Net | ASP.NET | Deployment | IIS | Tools | WebDeploy
Monday, August 16, 2010 7:21:00 AM (W. Europe Daylight Time, UTC+02:00)
Tuesday, June 08, 2010

Update 15th June 2010: Downloads are now available:

I've finally found the time to encode the recording we did when Udi Dahan visited us at NNUG Bergen and presented NServiceBus. In the first video, Udi talks about why or why not you should use a bus. The second video demos NServiceBus in action.

The original plan was to have a screen recording as well as video, but because of some network problems that plan failed. In the first video you can see me hacking on Udi’s computer to try and get the internet connection to work :-) Sorry about that.

We plan to get a permanent solution in place for publishing videos (not my blog :-)), but for now I’ve posted them here and we'll see how long my server/broadband can withstand the traffic :-) I used IIS Smooth Streaming for this one, so that should help a lot. Let me know if you have any problems. The quality should be quite good so full screen viewing is probably a good option (especially on the second video).

Udi Dahan on NServiceBus – Part 1

Udi Dahan on NServiceBus – Part 2

Tuesday, June 08, 2010 8:18:00 PM (W. Europe Daylight Time, UTC+02:00)
Monday, April 19, 2010

When working with passive federation you quickly run into Home Realm Discovery (HRD) (I couldn’t help notice that the short name became HRD which reads HARD :-) ). Anyways, HRD is about which identity provider (IP-STS) should authenticate the user and how to properly redirect the user to their home IP-STS. One example where HRD comes into play is when an organization have multiple partners that authenticate using their own internal STS. An example of that is illustrated in Figure1 below:

image
Figure 1

The Default Behavior
Using ADFS 2.0 as RP-STS you will by default be presented with this screen when you have trusts to one or more IP-STS’s:

image
Figure 2

Home Realm Query String
You probably do not want to reveal all of your federated partners like this. A better solution is to add a query string to the application URL where you specify the home realm, like this:

https://someWebApp/?whr=[Home Realm URI)

If the home realm (IP-STS) is ADFS 2.0, and using the URLs from Figure1 above, the URL would be:

https://rp.mydomain.com/?whr=https://ip-sts.partner1domain.com/adfs/services/trust

Let WIF Know About WHR
In order for your RP-STS to receive the whr parameter and automatically redirect the user to his home realm, you need to plug into the WIF pipeline of your application. You can do this very easily by editing your Global.asax.cs and listen to the RedirectingToIdentityProvider event like this:

using Microsoft.IdentityModel.Web;
...
protected void Application_Start(object sender, EventArgs e)
{
    FederatedAuthentication.WSFederationAuthenticationModule.RedirectingToIdentityProvider += new EventHandler<RedirectingToIdentityProviderEventArgs>(WSFederationAuthenticationModule_RedirectingToIdentityProvider);
}
void WSFederationAuthenticationModule_RedirectingToIdentityProvider(object sender, RedirectingToIdentityProviderEventArgs e)
{
    e.SignInRequestMessage.HomeRealm = Request["whr"];
}

Remove The Manual Home Realm Selection From ADFS
The next thing you probably want to do is prevent the RP-STS of displaying its home realm selection page. I didn’t find clear guidance of how to do this, but I found a solution that works. In the ADFS web folder of the RP-STS (C:\inetpub\adfs\ls\) you can edit the HomeRealmDiscovery.aspx and HomeRealmDiscovery.aspx.cs to display a message to the user and remove the dropdown for selecting home realm.

In HomeRealmDiscovery.aspx I removed the <div class="GroupXXLargeMargin"> section and changed the message “The site that you are accessing…” to something more informative. In the HomeRealmDiscovery.aspx.cs page I commented out everything related to the PassiveIdentityProvidersDropDownList control.

<%@ Page Language="C#" MasterPageFile="~/MasterPages/MasterPage.master" AutoEventWireup="true"
CodeFile="HomeRealmDiscovery.aspx.cs"
ValidateRequest="false"
Inherits="HomeRealmDiscovery" Title="Sign In"%>
<%@ Register TagPrefix="adfs" Namespace="Microsoft.IdentityServer.Web.UI" assembly="Microsoft.IdentityServer" %>
<%@ OutputCache Location="None" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
    <script type="text/javascript" src="FederationPassiveJScript.js"></script>
        <div class="GroupXLargeMargin">
            The site that you are accessing requires Home Realm Discovery to sign in. Please contact your system administrator for further details.
        </div>
        <asp:Panel ID="CardSignInPanel" Visible="False" runat="server" CssClass="GroupXXLargeMargin">Or, <a href="#" onclick="InfocardLink_onclick( document.infoCardObject );">sign
        in</a> with an Information Card.
            <adfs:InformationCardControl ID="InformationCard" runat="server"></adfs:InformationCardControl>
            <script>
                AddOnload( LoadCardPanel );
            </script>
        </asp:Panel>
</asp:Content>

HomeRealmDiscovery.aspx

//------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//------------------------------------------------------------
using System;
using Microsoft.IdentityServer.Web.Configuration;
using Microsoft.IdentityServer.Web.UI;
/// <summary>
/// This page enables home realm discovery if this STS is configured to trust multiple claims providers.
///
/// If the persistIdentityProviderInformation setting is enabled and the user has previously
/// selected a claims provider, that claims provider will be used automatically.
/// </summary>
public partial class HomeRealmDiscovery : Microsoft.IdentityServer.Web.UI.HomeRealmDiscoveryPage
{
    protected void Page_Init( object sender, EventArgs e )
    {
        //PassiveIdentityProvidersDropDownList.DataSource = base.ClaimsProviders;
        //PassiveIdentityProvidersDropDownList.DataBind();
        if( IsIssuedTokenViaSelectorEnabled() )
        {
            InformationCard.TokenSubmitted += TokenSubmitted;
            CardSignInPanel.Visible = true;
        }
    }
    private bool IsIssuedTokenViaSelectorEnabled()
    {
        foreach( AuthenticationTypeElement authenticationType in FederationPassiveConfigurationSection.Current.AuthenticationTypes )
        {
            if( authenticationType.Name == "IssuedTokenViaSelector" )
            {
                return true;
            }
        }
        return false;
    }
    protected void TokenSubmitted( object sender, InformationCardControl.TokenSubmittedEventArgs e )
    {
        SignIn( e.Token );
    }
    //protected void PassiveSignInButton_Click( object sender, EventArgs e )
    //{
    //    SelectHomeRealm( PassiveIdentityProvidersDropDownList.SelectedItem.Value );
    //}
}

HomeRealmDiscovery.aspx.cs

You then get a page like this if no whr is provided:

image  

Anything I can do about that URL?
If you don’t want your users to relate to the rather cryptic URL needed to support HRD there are several ways to make it a bit more user friendly. I will give a few suggestions here, but there are probably other (and maybe better) solutions than I can come up with right now.

  • Provide a shortcut on your users desktop or similar and have them use this to access the application
  • Detect by IP range and redirect to proper IP-STS
  • Provide a nice URL redirect either from the Relying Party (application) or IIS. E.g. https://someWebApp/YourCompany/ redirects to https://rp.mydomain.com/?whr=https://sts.yourCompany.lan/adfs/services/trust

One thing to note if you have the default settings in the web.config file for your RP-STS, specifically the <persistIdentityProviderInformation> set to true, is when a user have been redirected correctly to his/her home realm the RP-STS will issue a cookie to the user which contains the user’s home realm. If the user at a later time access the application from its root URL, he will be automatically redirected to his home realm. This is however only true as long as the cookie has not expired or the user uses the same computer as he did when the cookie was issued. Because of this I prefer sticking to one of the solutions above and not rely on the users having this cookie.

.Net | ADFS | Security | WIF
Monday, April 19, 2010 6:00:00 AM (W. Europe Daylight Time, UTC+02:00)
Saturday, April 17, 2010

Yesterday I had my Windows Identity Foundation (WIF) talk at MSDN Live in Stavanger. My last slide on that talk listed a set of resources to help you get started and understand WIF, Claims based Identity, Federation, Security Token Services (STS) etc, so I thought I’d share them here:

Tools and frameworks

WIF
Shouldn’t be too hard to find, but I provide the link anyways. This is formerly known as the Geneva Framework.

WIF SDK
This SDK will add some nice tooling support to Visual Studio for adding a reference to a Security Token Service (FedUtil). There is also a set of coding examples as part of this download.

AD FS 2.0 RC
Formerly known as Geneva Server, this is Microsoft’s Security Token Service with Active Directory integration.

StarterSTS
This is a open source project created by the security expert Dominick Baier from ThinkTecture. What makes this project interesting (except from using WIF to implement an STS) is that it has full support for the ASP.NET membership provider as well as having a OpenID bridge and a REST endpoint. On this web site you’ll also find a good collection of screen casts by Dominick showing you how to do various things in/with StarterSTS.

Books, whitepapers and coding examples

A Guide to Claims-Based Identity and Access Control (PDF Book)
This is a real must to get a proper understanding of WIF, SSO and Federation. They’ve done a great job explaining these concepts in a simple manner. This without using the many technical terms within the security domain throughout the paper, but rather spend time in the beginning to explain them so you have the proper understanding should you run across these terms in other resources.

Identity Developer Training Kit
This training kit (updated in March) have some great examples of how to do Active and/or Passive federation in ASP.NET, Silverlight, WCF and Azure. Highly recommended learning resource.

A collection of Whitepapers (older but still valuable)
The download includes:

  • David Chappell’s Claims Based Identity for Windows
  • Keith Brown and Sesha Mani’s WIF Whitepaper for Developers
  • Windows Identity Foundation - Changes between Beta 2 and RTW
.Net | ADFS | Security | WIF
Saturday, April 17, 2010 6:00:00 AM (W. Europe Daylight Time, UTC+02:00)
Tuesday, February 09, 2010

image I’m happy to say I was invited by Microsoft to join their MSDN Live tour in Norway this spring. I’ll be talking about Windows Identity Foundation (WIF) (used to be Geneva) which I find to be at great help simplifying authentication and authorization in small shops as well as in the enterprise.

I’ll be showing how you can take advantage of Claims (link is a PDF) in your applications today and why that is a good idea, how to easily integrate with Active Directory using Active Directory Federation Services (ADFS), how to create a custom Security Token Service (STS) and cover parts of the tiny topic of: how to do Federation in the enterprise :-)

Remember that the concepts around WIF, like Claims and STS, is nothing new and is not something that Microsoft has invented. It’s been around for many years and are supported on many platforms as well as programming languages.

Personally I’m quite excited about this new framework, cause it particularly helps us at Frende solve some pain points we’ve had to tackle around authentication with a lot of different sign-on methods and applications, and ease the use of SSO. We can now delete a lot of code, since WIF takes care of a lot of the plumbing we previously had to do ourselves. Less code to maintain is always good!

For more information about the agenda, have a look at Rune Grothaug’s blog: http://blogs.msdn.com/grothaug/pages/msdn-live-april-2010-en-fest-for-utviklere.aspx

I expect the official MSDN Live and TechNet site to be updated with the spring agenda very soon: http://www.microsoft.no/live/

The cities and dates are:

Stavanger: 16th of April
Trondheim: 20th of April
Bergen: 23rd of April
Oslo: 26th of April

Tuesday, February 09, 2010 10:02:26 AM (W. Europe Standard Time, UTC+01:00)
Thursday, January 14, 2010

logo_qcon Going to QCon London? I am and a bunch of my friends are too! Just a heads up that the early bird is about to expire this Friday.

If you haven’t been to QCon before, I can really recommend it. What I find especially attractive by this conference is its various tracks that should satisfy the most demanding devs and architects, and of course not to mention the speaker list (which is still growing). Here’s a few selected speakers from my point of view:

  • Dan North
  • Floyd Marinescu
  • Jim O. Coplien
  • Joe Armstrong
  • Jon Skeet
  • Kevlin Henney
  • Michael T. Nygard
  • Ola Bini
  • Ayende (Oren Eini)
  • Rod Johnsen
  • Ryan Slobojan
  • Stefan Tilkov
  • Steve Freeman
  • Udi Dahan
  • Ulf Wiger

And here’s the tracks:

  • Architectures You've Always Wondered About
  • Dev and Ops: A single team
  • Functional programming
  • Non-Relational DBs & Web Oriented Data
  • Software Craftsmanship
  • Solution Track: Wednesday
  • 2015 Software Development
  • Agile Evolution
  • AlphaGeeks on .NET
  • Cloud Solutions
  • Irresponsible Architectures and Unusual Architects
  • Solutions Track: Performance and ScalabilityBrowser as a Platform
  • Cool Stuff with Java
  • How do you test that?
  • SOA 2010
  • The Concurrency Challenge

Hope to see you in London March 10-12 (March 8-9 for tutorials).

Thursday, January 14, 2010 8:13:05 PM (W. Europe Standard Time, UTC+01:00)
Sunday, August 23, 2009

The Community For MVC.NET will be running a Live Meeting with Phil Haack on August 26th @ 9am PST (4pm GMT / 6pm CET) on upcoming MVC 2 features.

.Net | ASP.NET | Events | MVC
Sunday, August 23, 2009 9:52:55 PM (W. Europe Daylight Time, UTC+02:00)

imageEven though I don’t develop software in SharePoint, this blog post by Lee Richardson reflect my thoughts and worries about SharePoint development.

The essence of his post is in this paragraph:

But the power given to end users makes rigor and good design extremely hard for developers because the production machine you deployed to last month may look completely different now that you’re ready to redeploy. And Microsoft makes good design even harder with an inflexible API. Critical classes like SPSite (think SqlConnection) contain no public constructor, rendering them completely unmockable (unless you’re willing to spend $450 per developer for some TypeMock Isolator magic). And vital classes like SPList (think DataSet) are marked final, crippling your ability to make nice strongly typed entities in your architectures.

Lee proposes some techniques to use that you should read in his post, but it’s half baked and not good enough in my opinion. The things he suggests (which is usually taken for granted on any other project) is made really hard to do by MS. Should MS rethink the way SharePoint is architected for the sake of developers to ease maintenance, improve code quality and basically allow developers working with ShapePoint to be craftsmen? Or is the dynamics of the product given to the end user so good that it’s worth all the extra efforts?

Sunday, August 23, 2009 12:46:38 AM (W. Europe Daylight Time, UTC+02:00)
Monday, August 03, 2009

It's tempting to just leave this blog post with that statement only :-) I will however explain this a bit further for those of you who either are forced to write comments (like by your boss or a policy at your company), or actually believe a lot of comments in code increase readability and ease maintenance.

I'm not trying to be sarcastic, I just believe 100% in code and not in comments. In .NET and most other OO languages there are two types of comments. The first type is the one you write in your code to explain what your code does. Like this:

//Calculate interest
double amount 
    = balance * Math.Pow(1 + (annualPercentage / 100) / 365, days)
      - balance;

How do you replace this comment with code? What about this:

double amount = CalculateInterest(balance, annualPercentage, days);

Whenever you come across comments like the above, I encourage you to refactor by replacing comments with code. Often you don't even have to extract a method like above, but just give better names to variables.

The second type of comments is the ones you use to generate API documentation:

/// <summary>
/// Calculate interest
/// </summary>
/// <param name="balance">Current balance of the account</param>
/// <param name="annualPercentage">Annual percentage</param>
/// <param name="days">Days to calculate interest for</param>
/// <returns>Interest amount</returns>
public double CalculateInterest(double balance, 
                                double annualPercentage, 
                                int days)
{

Almost on every project I've been on we've had these comments/documentation. Also, on the same projects they've never been used for anything useful. I've actually forced devs to do this myself! If you're creating a product/framework to be used by other devs, writing this type of documentation makes sense. If you don't, it makes no sense! I used to do this just to satisfy my own satisfaction of generating a chm file and see that all my methods and classes was documented. That was about it. I never used it once! It's much easier to look in the code than to look at the API doc.

The worst thing about this type of documentation is that it clutters your code and makes the code hard to read. A class with 50 lines of code becomes 100 lines with comments. As a practice, try to remove all comments and see if it's easier to understand and read the class. I strongly believe it is. If not, it's a code smell and you should refactor your code! Comments should not be used to explain bad code.

When I talk to people about comments in code I often ask them two questions:

Do you think it's hard to maintain code?

How hard to you think it is to maintain comments?

If you change your code, do you also make sure to check if the comments are still correct after you've done the changes? Most people don't and you shouldn't really need to worry about it. Outdated comments can create confusion and bugs just because someone forgot to update them.

Monday, August 03, 2009 12:36:48 AM (W. Europe Daylight Time, UTC+02:00)
Sunday, July 19, 2009

At QCon London 2009, Dan Bergh Johnsson had a talk on the DDD track about how to make use of Value Objects (VO's) (The Power of Value - Power Use of Value Objects in Domain Driven Design (PDF)). In his talk he took a piece of code and refactored it into a better piece of code by using VO's. By doing this Dan showed some really good concepts of using VO's. Even though I knew about the concept of VO's before his talk, he made me realize many new scenarios where they are applicable. And more importantly that it is not limited to DDD.

So what is a VO anyway? Is it related to value type in .NET?

To answer the last question first: The real answer is no, but the way I see it there is a relation. A value type in .NET is everything that is not an object. Typically simple types like int, char, double, but also enums and structs. The relation is that often you find yourself creating VO's where value types was previously used. It is however not limited to value types.

Now to the first question. I first came across VO's after reading Evans DDD book (commonly known as the blue book). In DDD a Value Object is an object without an Id and are usually immutable. In examples of VO's, Address is commonly used, which I don't find particularly useful. I think Address way too often has an Id and people have a hard time relating to that as a Value Object. I find the Amount example I gave in an earlier post to a better example or the one below illustrated as an interface (borrowed from Dan):

public interface IPhoneNumber {
  bool IsValid {get;}
  string Number {get;}
  string AreaCode {get;}
}

How many times have you used the concept of a phone number in your code? Like mobile, fax, fixed etc… How often have you kept it as a string? How much code do you have for doing different types of validation, getting area code etc? Do you have it all in one place or scattered around in different places? Other examples are Money, ZipCode etc… These are great candidates for Value Objects.

Now that we know what Value Objects are, what is so powerful about them and why should I use them more? Great question :-) Below is my three reasons:

  1. Code readability - I find that using Value Objects greatly improve the overall code readability and eliminates comments. Just like good names on methods and properties does.
  2. DRY (Don't Repeat Yourself) - By having a Value Object for PhoneNumber, you avoid writing code to handle specific cases around phone numbers and you reuse them wherever the concept of a phone number is used.
  3. Helps people getting back into OO thinking – We who have been living in the Microsoft .NET world for a long time have been thought to think of programming from a data/database perspective and not object oriented programming as we once learned it. In other words: think of behavior instead of data.

When I started to use VO's, I soon discovered I used them all over. They really add great value to my code. As an example, lets implement the IPhoneNumber above:

public class PhoneNumber : IPhoneNumber
{
    private readonly string _phoneNumber;
    public PhoneNumber(string phoneNumber)
    {
        _phoneNumber = phoneNumber;
    }
    public bool IsValid
    {
        get { return Regex.IsMatch(_phoneNumber, @"^[01]?[- .]?(\([2-9]\d{2}\)|[2-9]\d{2})[- .]?\d{3}[- .]?\d{4}$"); }
    }
    public string Number
    {
        get { return _phoneNumber; }
    }
    public string AreaCode
    {
        get
        {
            return Regex.Match(_phoneNumber, @"^[01]?[- .]?(\([2-9]\d{2}\)|[2-9]\d{2})").ToString();
        }
    }
}

The above code handles US phone numbers. To be used in a production system there should probably be even more validation in the regexp's, but I hope the example gives you and idea of what I'm thinking.

.Net | Architecture | CSharp | DDD | Patterns
Sunday, July 19, 2009 1:29:12 PM (W. Europe Daylight Time, UTC+02:00)

One of the code smells I see most often in C# and other OO languages is the misuse of switch/case statements. When I was a young Jedi (some might argue I still am :-)) I didn't see anything wrong with using the switch statement. Actually there still are a few cases where it's still applicable, but most usages I come across should have been solved differently. So why is this? What is so bad with the switch statement?

As Dan North tweeted me when I asked for the perfect refactoring solution for switch statements :-) :

A switch is often a sign of behaviour that should live elsewhere - so where should the code in the cases live?

Functions should only do one thing, the one thing which they state. Like CalculateInterest and ConvertDateToString should do exactly that; calculate interest and convert a date to string. Since switch always reside inside functions it almost always violates that principle.

Let's look at what Uncle Bob (Robert C. Martin) says in his Clean Code book about switch statements:

Even a switch statement with only two cases is larger than I'd like a single block or function to be. It's also hard to make a switch statement that does one thing. By their nature, switch statements always do N things.

My answer to Dan's question above was using polymorphism. The cases should live in their own classes. By doing that you don't have to modify existing code when introducing new behavior, you just create a new state (read class). Btw Dan is really good at asking questions to questions where you end up answering your own question :-)

Enough with the coding theory. Below is a method using a switch statement for getting messages from different systems. Typically these are systems that another system depends on (the system containing the below code). The messages might be if the system is available or not, or if there are any maintenance planned.

public string GetSystemMessage(System system)
{
    switch (system)
    {
        case System.System1:
            return GetSystem1Message();
        case System.System2:
            return GetSystem2Message();
        case System.System3:
            return GetSystem3Message();
        case System.System4:
            return GetSystem4Message();
        default:
            throw new ApplicationException("System not found");
    }
}

This is actually quite a good switch. It uses return instead of break and it only has one line per case. If you can't avoid writing a switch, this is how you should do it.

Now let's pull it apart and make it better and extendable. Time for refactoring.

Polymorphism by using Strategy Template Pattern
Here's my code using the Strategy pattern:

public interface ISystemStrategy
{
    string GetMessage();
}
public class System1Strategy : ISystemStrategy
{
    public string GetMessage()
    {
        return "System1";
    }
}
public class System2Strategy : ISystemStrategy
{
    public string GetMessage()
    {
        return "System2";
    }
}
public class System3Strategy : ISystemStrategy
{
    public string GetMessage()
    {
        return "System3";
    }
}
public class System4Strategy : ISystemStrategy
{
    public string GetMessage()
    {
        return "System4";
    }
}
public class SystemMessenger
{
    private readonly ISystemStrategy _system;
    public SystemMessenger(ISystemStrategy system)
    {
        _system = system;
    }
    public string GetMessage()
    {
        return _system.GetMessage();
    }
{
}

First I define an interface to be used by the different systems (ISystemStrategy) and next each system (1-4) implements that interface, resulting in a class for each case in the switch.In addition I have a class called SystemMessenger that is responsible for accessing the system and get a message.

The switch can now be replaced by this code:

public string GetSystemMessage(ISystemStrategy system)
{
    return new SystemMessenger(system).GetMessage();
}

Note that the "client" only relates to the SystemMessenger class and not to the different implementations of ISystemStrategy.

The benefit of this code might not be obvious. Actually it might give the impression that this was a lot of code for almost nothing. Well, don't be fooled. The strongest aspect of the above solution is that you don't have to change the GetSystemMessage later when/if a new system is added, you just implement a new class.

To prove the above, here's what I need to do to introduce a new system:

public class System5 : ISystemStrategy
    public string GetMessage()
    {
        return "System5";
    }
}

To use the new system, an instance of System5 will be sent into GetSystemMessage just as before, and SystemMessenger handles the rest as before. No code change!

Dictionary
Another refactoring option is using some type of lookup table. In my example I'll use a dictionary together with the Func<TResult> delegate. However, I don't recommend doing this unless you have a really good reason to do so. Stick with the Strategy pattern if you can.

public class SystemMessengerDictionary
{
    private readonly Dictionary<System, Func<string>> _systems;
    public SystemMessengerDictionary()
    {
        _systems = new Dictionary<System, Func<string>>
                           {
                               {System.System1, GetSystem1Message},
                               {System.System2, GetSystem2Message},
                               {System.System3, GetSystem3Message},
                               {System.System4, GetSystem4Message}
                           };
    }
    public string GetSystemMessage(System system)
    {
        return _systems[system]();
    }
    //GetSystemX Methods
    ...
}

I decided to show this example even if I don't like it. The reason is that it is better than the switch. The worst about this in my eyes is that the enum is still there. I just hate enums! When reading the code they look like classes with interesting behavior, but then you discover they're just glorified int's :-|

Conclusion
Hopefully this example will help you understand why switch is something you should avoid and also give you an example of how it should be done. But before you consider doing any refactoring of existing code, consider a second question Dan asked (answered?) me:

How would it evolve if you added a few more cases? And how likely are a few more cases?

This is an important question, because you don't want to refactor just for the sake of refactoring. Keep this in mind before making use of any of the suggested solutions above.

Sunday, July 19, 2009 12:53:15 AM (W. Europe Daylight Time, UTC+02:00)
Tuesday, June 23, 2009

Recently I worked with a colleague on some code using decimal.TryParse() and tried to find a better way of using it. Specifically I had a string value representing a currency amount entered by a user in a web form. The amount needed more than just normal validation, so I needed to do some stuff with it.

Here's the code I started with:

public void SomeMethod(string userEnteredAmount)
{
    decimal amount;
    if(decimal.TryParse(userEnteredAmount, out amount) {
        //Do some stuff with amount
    }
    else {
        //Show message to user about invalid amount
    }
}

I've recently found many cases where I find the use of Value Objects to be very applicable. I found this case to be a particularly interesting example. Anyway, I created a Value Object called Amount to abstract away the TryParse stuff. Below is the class I created.

public class Amount
{
    private readonly decimal _value;
    private readonly bool _isValid;
    public Amount(string amount)
    {
        _isValid = decimal.TryParse(amount, out _value);
    }
    public decimal Value
    {
        get { return _value; }
    }
    public bool IsValid
    {
        get { return _isValid; }
    }
}

See how clean it got? At least I think so. The important part though is that it's usage is so much easier to understand and read:

var amount = new Amount(userEnteredAmount);
if(amount.IsValid) {
    //Do some stuff with amount.Value
}
else {
    //Show message to user about invalid amount
}

It's more code, but cleaner. Or did I say that already? :-) And of course it's reusable other places where amount has a meaning.

.Net | CSharp | DDD | Patterns
Tuesday, June 23, 2009 12:17:10 AM (W. Europe Daylight Time, UTC+02:00)
Thursday, April 30, 2009

A good friend of mine, Mark Nijhof, will be doing a presentation on FubuMVC at the next European Virtual Alt.NET meeting. Mark is actively involved with the alternative MVC framework for ASP.NET together with Chad Myers and Jeremy D. Miller. Mark will also do a Fubu presentation at NNUG Bergen 27th of May (invitation will be available soon).

If you want to know more about FubuMVC you can check out the interview I did with Chad on InfoQ and of course their public website. I encourage you to download Fubu and try it out, cause it has some interesting differences which I personally like compared to ASP.NET MVC.

Also, Jeremy Miller is coming to Bergen and NNUG in mid June just before NDC (thanks Mark for organizing this!), so I’m really looking forward to that. A lot of stuff happening at the local community in Bergen at the moment!

.Net | ASP.NET | NNUG | Patterns
Thursday, April 30, 2009 9:07:29 PM (W. Europe Daylight Time, UTC+02:00)
Saturday, April 04, 2009

Yesterday I published an interview I did with Chad Myers about FubuMVC on InfoQ. FubuMVC is a Model-View-Controller (MVC) implementation in ASP.NET. Much like ASP.NET MVC, but with some interesting differences. I encourage you to check it out!

Thanks to Chad and Jeremy D. Miller for agreeing to this and for giving great answers to my questions! And to Mark Nijhof for interesting discussions around MVC in general and Fubu in particular!

Saturday, April 04, 2009 9:03:03 PM (W. Europe Daylight Time, UTC+02:00)
Monday, March 30, 2009

This article is a translation of a Norwegian article I wrote earlier that got published on IT Pro a few days ago. It’s targeted towards IT decision makers and leaders, does not contain my usual technical focus, but should still be a valuable read for developers not familiar with Azure or want to know more about cloud computing.

Azure

Software and services developed by software providers today are primarily deployed on internal servers or made available through hosting providers. The “Cloud” opens a whole set of new possibilities, both functionally and financially. Several providers are shaping this new service and one of them is Microsoft with the Azure Services Platform (Azure).

This article will focus on what the “Cloud” has to offer software providers compared to today’s traditional services with focus on Azure specifically.

Scaling

Today it’s quite common, and almost acceptable, for websites to be temporary unavailable under extraordinary load. Examples can be ticket sales for popular concerts or some other event with limited time for registration. The load on the website is usually limited to a few hours, or even minutes, and the time is known in advance. What if you as a service provider could scale your services dynamically, to handle the increased traffic for that period? This is an example of what Azure has to offer.

Pay per use

Even though Microsoft have not officially revealed the details around the payment model for Azure, it’s natural to expect them to base their model on usage. Examples could be traffic in/out, storage, processing etc. Other providers, like Amazon and Google have similar models and it’s natural to believe that Microsoft will not deviate too much from these to be competitive.

Such a model will also be very attractive for startups. The cost of buying the necessary hardware, disk space, backup and broadband to run the website or service, not knowing how many will use it in advance, is often a good enough reason for not pursuing the opportunity. Taking advantage of a payment model like in Azure, the provider will have several advantages:

  • Small or no startup cost
  • Cost spread across time
  • Scaling on demand
  • Pay per use

    Microsoft’s biggest investment ever?

    clip_image001[4]There is a lot more behind Azure than software. To support such a scalable unit in the cloud a lot of investment in hardware, new technology and land areas is needed. One method Microsoft have used to build their datacenters, is to have preconfigured containers with server racks from HP and Dell, with built-in cooling and network. A lot of these containers are placed as close to a power plant as possible, where power is easily accessible, and when connected they are up and running in the cloud. All administration are then done remotely.

    If one, two or five servers in a container stop working, it will have no effect on data or traffic for the user of the cloud. Azure is designed so that servers can be pulled in and out of the cloud without affecting the service. This says a lot about the size and investment put in place for this to be a reality.

    Many datacenters are under construction several places in the world. One reason for Microsoft to build at several locations, and not just in the US, is to avoid the physical laws related to data transfers over the internet. Another important factor is the different regulations on different continents. As an example, some don’t want to have their data stored on servers in the US, in case the government demands to get access to their data. There is also difference in regulations in e.g. the US and Europe, that Microsoft needs to take into consideration.

    Built on known Microsoft products

    AzureArch

    Azure contains quite a few services as illustrated on the image on the left. Even though many of these services have new names, they are based on Microsoft’s existing products.

    Liver Services is a cloud service based on Windows Live, .NET Services on Microsoft .NET, SQL Services on SQL Server etc. These services are built on top of Windows Azure, which is a operating system specifically designed for running in the cloud. Windows Azure cannot be accessed as a regular operating system (through e.g. Remote Desktop), but developers can communicate with Windows Azure through a Application Programming Interface (API).

    Compared to Amazon’s cloud solution, where the user have direct access to the operating system (Linux or Windows), the user don’t have to worry about security or software updates, backups etc, since this is automatically managed by Microsoft.

    Security

    Security has been a central part of the development of Azure. The consequences of somebody getting unintentional access to services or data in the cloud would be catastrophically. Microsoft has built in many security mechanisms to avoid this. Some examples are data encryption, Code Access Security and backups to mention a few. It is expected that this is an area where users, developers, owners and Microsoft themselves will focus their efforts on in the time to come. Roy Ozzie, Chief Architect at Microsoft, says it’s extremely important for Microsoft to build trust in companies looking to invest in Azure as a possible solution, and that this is critical for the success of the cloud1.

    Microsoft have also made available a service they call .NET Access Control Service, that aims to support many of today's identity providers. By integrating the common identities that customers use or are common in a region (like a country or EU), this service can solve some of the identity issues we have today. Many are tired of having to create a new id every time they access a new website that has some type of identification, to display user specific information. What if the user could use only one, ore a handful identities, and choose which one to use towards a given website? By implementing .NET Access Control Service the user can do this and the web application can decide to trust it or not.

    Development tools with support for Azure

    Microsoft have made available a range of tools aimed for developers creating applications running on Azure. Already today developers can create and deploy application on Azure by using Visual Studio 2008 SP1, and develop in ASP.NET. The only requirement is for the developer to register in order to get access to the Azure services.

    In addition to the normal development tools, Microsoft has made it possible to develop and test on a local variant of the cloud on the developer’s computer. This will enable debugging of code during development and not have to deploy to the cloud every time a new functionality needs testing.

    When will Azure go live?

    Azure is available for developers today in Beta, so that they can already now try out the service and look at the potential possibilities. The service is however limited in this first Beta release, which makes it unattractive for production use. Steve Ballmer have stated that Azure will go live under Professional Developers Conference 2009 (PDC09) that is scheduled for 17th of November 20093.

    Conclusion

    With this new service, together with Microsoft and others investments in the technology, possibilities will arise that before was either very difficult or economically irresponsible to target. Examples where startups and smaller companies can bet big without enormous investments, where scaling opens up completely new possibilities and data processing taken to new heights, makes the cloud an attractive service for the future. It’s still too early to predict if this is going to be a success or not, but it’s clear in which direction the biggest providers are going.

    Sources:

    1Ozzie: Success of Azure comes down to trust - http://news.zdnet.co.uk/software/0,1000000121,39532953,00.htm

    2Introducting the Azure Services Platform by David Chappell - http://download.microsoft.com/download/e/4/3/e43bb484-3b52-4fa8-a9f9-ec60a32954bc/Azure_Services_Platform.pdf

    3Ballmer: Azure ready for release by end of year - http://www.infoworld.com/article/09/02/24/Ballmer_Azure_ready_for_release_by_end_of_year_1.html

    Monday, March 30, 2009 7:48:14 PM (W. Europe Daylight Time, UTC+02:00)
    Monday, February 16, 2009

    VAN = Virtual ALT.NET (in case you where wondering).

    REST with the OpenRasta framework, 25th of February 07:00 PM GMT (20:00 CET).

    http://www.lostechies.com/blogs/colinjack/archive/2009/02/15/europe-van-25th-february-2009.aspx

    Monday, February 16, 2009 5:56:09 PM (W. Europe Standard Time, UTC+01:00)
    Sunday, February 08, 2009

    Greg Young is sharing his wisdom around DDD at the first ever European ALT.NET meeting at 7PM GMT. Attendee URL: http://snipr.com/virtualaltnet (Live Meeting)

    Friendly reminder: If you don’t have the Live Meeting client installed you should do that before the meeting starts. Just click on the attendee URL above and follow the instructions.

    .Net | DDD | Events
    Sunday, February 08, 2009 9:54:28 PM (W. Europe Standard Time, UTC+01:00)
    Saturday, February 07, 2009

    This interview kind of slipped my radar. Actually I didn’t have time until now to actually watch it. Now when I had however, I sincerely recommend everybody who’s slightly interested in DDD to watch it. It’s only 30 minutes.

    One of the more interesting things he talked about, was have the domain model care only about writes. This is something for my x co-workers at Contiki to have a look at (guys, I believe this could help you out). Why is this interesting and not only nuts!? Well, it opened up a door for me related to my concerns around the usage of DTO’s. Why would I want to transform all my domain objects to DTO’s for the sake of moving it to some client to display data on a screen?

    Greg suggest using DTO’s for displaying data to the user (think of it as a report), and pushing all your writes through your domain model (all changes to your domain). By doing this you get domain objects without getters and setters! That shouldn't be a goal in itself, but think about what it really means… Done thinking? Let me add a few more … (dots) Ok, ok… It means (as I interpret it) you create a separation between what your system needs to show to the end user and what your domain should care about. Why clutter the domain with reports?

    If you have any thoughts about this, please let me know. Thanks.

    Saturday, February 07, 2009 8:48:03 PM (W. Europe Standard Time, UTC+01:00)
    Friday, January 16, 2009

    InfoQLogo My article about The Future of Microsoft .NET Programming Languages just got published on InfoQ.This is my first attempt at being an editor for them, so if this works out I hope you will see more stuff from me in the near future.

    Would love to hear what you think, so drop me a comment if you like.

    Friday, January 16, 2009 2:56:53 PM (W. Europe Standard Time, UTC+01:00)
    Monday, December 22, 2008

    In my previous post about Azure Services Platform I summarized many of David Chappell’s points in his talk last week as well as Clemens Vasters intro to .Net Services. One of the things David mentioned was other cloud providers that exist today.

    One that I find particularly interesting is Amazon. In this article I will cover the Amazon Web Services and how they map to Azure Services Platform. Amazon is my starting point, so I will not talk about the services that Microsoft have that Amazon don’t, unless they are tightly connected to one of Amazon’s services. One thing to note though is that Amazon has been offering cloud services for a while and some of their services are already out of Beta. MS however is just getting started so it’s not easy to know where MS is going to end up compared to Amazon. In other words; this article might be out of date pretty soon! :-) Saying that, some design decisions needs to be taken early and some decisions can’t easily be reverted, so many of the differences and similarities between the two providers will probably be around for a while. And when people from Microsoft are going to Amazon, maybe the similarities between the two will increase even further…

    Actually, talking about mappings, lets get the first mapping out of the way: Amazon Web Services maps to Azure Services Platform.
    AmazonVSAzure

    Amazon EC2
    Amazon Elastic Compute Cloud (EC2) is a virtual computing environment that let you create virtual servers in the cloud. Either Linux or Windows based. Windows based OS’s (Windows Server 2003) are in Beta and only available at the datacenters in the US, but I’m expecting Europe to provide this service soon. By creating or using a predefined Amazon Machine Image (AMI) and adding your application to the same image, you get your application into the cloud. By using the EC2 web services or any of the configuration applications out there (like Elasticfox) you can configure your virtual images, security, network access and more. To do actual work on the image (like installing applications) you just RDP into that server and do your install or configuration.

    Amazon EC2 vs. Azure Services Platform
    EC2 can be compared with Windows Azure. What Amazon let’s you do which Microsoft don’t, is have direct access to the virtual image. You can RDP (Remote Desktop) into the server and do whatever you want and install whatever. Windows Azure gives you an API where you can configure stuff like logging and alerts. According to MS they will provide more services to interact with Windows Azure later, but I don’t think you will get access to the actual virtual image(s). To add applications to Windows Azure you need to use either the Web Role or the Worker Role. However, windows Azure maintains the OS for you (updates and such) while on EC2 you have to do this yourself. Amazon today gives you a Windows 2003 Server while on Windows Azure it’s Windows 2008 Server. On Windows Azure you can configure how many instances of your Web/Worker role you want for scaling, while on EC2 you need to use the provided web services to spool up new instances.

    One thing Microsoft provide that Amazon don’t is the ability to have a local environment of “your cloud”. This allow you to do development on your local computer in a simulated cloud environment, which again will let you do things like debugging. You can of course to this on EC2 as well by installing Visual Studio :-)

    A common requirement for both is that the EC2 image and your Web/Worker roles need to be stateless. If not, scaling would just not work the way it’s indented.

    For more information: Amazon Elastic Compute Cloud (EC2) and Windows Azure

    Amazon S3
    Amazon Simple Storage Service (S3) is where you persist your data/files. Here you can store anything from files you need for your server to databases, downloadable files, or any files you want to store in the cloud. S3 exposes a web service you use to write, read or delete files (objects) up to 5 gig each. The number of files you can store is unlimited, but you of course have to pay for storage. The underlying structure is flat using a key/value pair to write and read (or delete). They use names like Buckets, Keys and Objects. A Bucket is similar to a file folder, a Key is the unique identifier for your object within a Bucket and the Object has metadata about the object you have stored (like created date, modified date, content type etc).

    Amazon S3 vs. Azure Services Platform
    Comparing this with Microsoft’s services is not a one-to-one mapping. To explain this I need to give you some details about the data services provided by Microsoft. First there are two main services:

    1. The data storage facility in Windows Azure
    2. Microsoft SQL Data Services (SDS)

    In Windows Azure you have three storing options:

    1. Blob
    2. Table
    3. Queue

    And to make the story short: Windows Azure with its Blob service is similar to S3 in my opinion.

    The ability to query data on S3 is limited compared to Windows Azure, but Amazon provide this service in their SimpleDB instead which integrates with S3 (more on this later). In Windows Azure you can use a LINQ like query language, but on S3 you’re limited to using a pre-known bucket and key. Both do however have similar url access:

    S3 example: http://torresdal.s3.amazonaws.com/photos/me.jpg

    Windows Azure example : http://torresdal.blob.core.windows.net/photos/me.jpg 

    In the S3 example; photos = Bucket, me.jpg = Key

    For more information: Amazon Simple Storage Service (S3) and Microsoft SQL Data Services (SDS)

    Amazon EBS
    Amazon Elastic Block Store allow you to do two things:

    • Create volumes
    • Create snapshots

    Volumes are storage volumes from 1GB to 1TB that can be mounted as a disk on EC2. They’re also placed in a Availability Zone, meaning you can only attach volumes to EC2 instances that run in the same zone.

    A snapshot is a copy of the complete volume at the time you took the snapshot. If a snapshot already exist, only the diff will be saved to save storage. All snapshots is stored in S3 for later retrieval. You can then use your snapshots to create new volumes based on one of your snapshots.

    Public Data Sets is free snapshots everybody can use. They contain big databases for things like public DNA data, transportation data etc. Typical data used for research. Though I’m not in that type of business or research, I see the perfect match for the service they’re providing.

    If you want to use your own database server (like SQL Server) you would use an EBS volume to store the database files to persist data. This will make sure that all your data are persisted in case the server goes down for some reason or another.

    As a side note I have to admit every time I read Elastic Block Store, my mind reads Elastic Book Store, which kind of makes sense considering who provides the service :-)

    Amazon EBS vs. Azure Services Platform
    As far as I know there is nothing equivalent on the Microsoft platform. Since they don’t have an open interface giving you direct access to the OS there is no need.

    For more information: Amazon Elastic Block Store (EBS)

    Amazon SimpleDB (Beta)
    Amazon SimpleDB lets you store, process and query data in the cloud. It is designed to scale and developers use provided web services to integrate with the service. There is also a connection between SimpleDB and S3 allowing you to query data in S3. SimpleDB is structured into domains which contains items which again contains attribute-value pairs, resulting in a flat and highly optimized data structure. Querying data is done through either the Select API or the Query API.

    Amazon SimpleDB vs. Azure Services Platform
    Comparing SimpleDB to MS is not strait forward. As mentioned previously when I talked about S3, Microsoft provide several services in this area. You have the data storage in Windows Azure with its Blob and Table data structure, and you have Microsoft SQL Data Services. All of these can be compared to SimpleDB, though they’re not an exact match. As the word Simple is suggesting, Amazon is providing a simple interface for storing data. Microsoft is giving you more options to how your data is going to be stored and structured, but all in they all have a flat structure similar to Amazon’s SimpleDB. Microsoft is however building on top of their existing database investments of SQL Server and provides similar services that we know from that platform in the cloud.

    For more information: Amazon SimpleDB, Windows Azure Tables and Blobs, and Microsoft SQL Data Services

    Amazon SQS
    Amazon Simple Queue Service (SQS) is, you got it, a queue. As with the other services they provide this is highly scalable and they provide unlimited numbers of queues to use as well as unlimited number of messages to add to a queue. The body of the message is limited to 8KB and a massage can be stored up to 4 days before it gets deleted. Though the message body is limited, you can use the body to reference data stored in e.g. S3 or SimpleDB. They provide you with four API’s: CreateQueue, SendMessage, ReceiveMessage, and DeleteMessage, and are exposed as web services.

    Amazon SQS vs. Azure Services Platform
    Compared to Microsoft this is the queue storage type in Windows Azure as I mentioned above (in the S3 section). But queues are often used in conjunction with workflows, and here Microsoft provide its own service. Amazon however does not have a separate service for workflows, but encourage the use of SQS for this. The Windows Azure Queue as described now has a main purpose of providing a communication facility between the WebRole and the WorkerRole. As with SQS also the Azure Queue have the same flexibility and limitation (unlimited queues, unlimited messages and a message size of 8KB). I could not find any information about how long MS stores messages in a queue, though I expect there to be one :-)

    For more information: Amazon Simple Queue (SQS), Windows Azure Queue and Microsoft .NET Workflow Service

    Amazon CloudFront (Beta)
    CloudFront is a service for distributing files. All files are stored in S3 but CloudFront is using a network of edge locations, so that users downloading/accessing files will get it from a location close to him or her. When a user request a file/object CloudFront will automatically route to the nearest edge location for best performance.

    Amazon CloudFront vs. Azure Services Platform
    Currently I cannot see a similar service from MS. There has been some speculation that Microsoft’s cache solution codenamed “Velocity” is their service in relation to CloudFrount, but I don’t see the match.

    Conclusion
    The similarities between the services provided by Amazon and Microsoft are striking. There are a lot of similarities on how they store, manage and query data. Especially that they both have chosen a flat data structure with no relational tables, which is the only sane thing to do when you want to scale I guess.

    The major differences are around how they expose their operation systems to the developer. Amazon gives you access via RDP to the virtual server, while MS adds services on top of their virtual servers that you can integrate with. Also since Amazon is not an OS or application manufacturer they are freer to chose which technologies to provide. Here Microsoft is more restricted to their own platforms and technologies, though they promise to support other programming platforms than .Net.

    So the final question to all of this have to be:

    Which one would you choose?

    Based on what I know about the two service providers now, I would go for the consultant answer… It depends :-) and answer with a new question:

    What are you going to use it for?

    If you have an existing application built around SQL Server that does not need to scale very much (like an enterprise app), Amazon seams like a good solution right now. If you’re starting from scratch and writing a new application that suits the cloud model, then I’m not that sure. Technology or programming platform will probably impact your decision. Looking into the future and if your a .Net developer choosing MS is probably a safe bet, because you would get great service support on their platform as well as a local version of Windows Azure on your desktop. On the other hand, Amazon’s solution is quite open and does not limit you to any programming language. The race is open and I’m excited to see where they are in a year or so…

    Monday, December 22, 2008 5:44:31 PM (W. Europe Standard Time, UTC+01:00)
    Thursday, December 18, 2008

    In my previous post about Azure Services Platform I linked to where you could find David Chappell’s presentation that I attended. Now Børge Hansen have made Clemens Vasters slide decks available too. You can find them all here:

    David Chappell (Azure Services Platform): https://cid-88b5769d9bbdf846.skydrive.live.com/self.aspx/Offentlig/Azure%20Services%20Platform--Chappell.pdf

    Clemens Vasters (.Net Services overview): https://cid-88b5769d9bbdf846.skydrive.live.com/self.aspx/Offentlig/NETServicesOverview-v2.pptx

    Clemens Vasters (.Net Services drilldown): https://cid-88b5769d9bbdf846.skydrive.live.com/self.aspx/Offentlig/NETServicesDrilldown-v2.pptx

    Thursday, December 18, 2008 7:08:00 PM (W. Europe Standard Time, UTC+01:00)
    Monday, December 15, 2008

    Last week I attended 2 sessions about the new Microsoft platform in the cloud: Microsoft Azure Services Platform. The first was held by David Chappell and the second by Clemens Vasters. Two great speakers. Unfortunately I didn’t get to see Clemens complete talk, because I had to catch a flight back home, but hopefully I got the main content of his talk.

    In this blog post I’m going to ask and answer some questions by the help of these two sessions + the additional study I’ve done around this topic.

    Disclaimer: The answers I provide below is based on my current knowledge of this platform and might not be correct now or in the future, though I’ve spent a fair amount of time making sure it is.

    What is it?

    It’s a platform where you can deploy and manage new services or even complete web applications into the “cloud”, in addition to make use of existing services already provided by the platform. This is often referred to as cloud computing. Today the Azure platform contains the following services: Windows Azure (the platform), Microsoft .Net Services, Microsoft SQL Services and Live Services. Microsoft SharePoint Services and Microsoft Dynamics CRM Services are also mentioned in relation to the platform. All of these services make up the Microsoft Azure Services Platform. By reading these names you may see the potential naming confusion? When you say Azure, do you mean Windows Azure or Azure Services Platform?

    Now you may ask, what is it really? From a simplified developers perspective it’s a platform on the internet (the cloud). Instead of hosting your web application/service on your local server, you publish it into the cloud. In addition it gives you access to the services you need to build a multi-tier architecture. From another perspective it’s big monster of a datacenter providing you with a lot of data power (virtual Win 2008 servers) to do your stuff, giving you the option to scale up and down at will or dynamically.

    How committed are Microsoft to this platform?

    As committed as they’ve never ever been before with anything as far as I can remember! They invest heavily in the technology and infrastructure needed to support this platform. By heavily I mean they’ve told the marked that this is such a huge investment that it will highly impact Microsoft’s money bin. As an example of this, here’s a short description of what they’re doing with their datacenters needed to host this beast:

    Every datacenter is set up of a grid of physical and virtual computers. These computers are delivered by HP and Dell and some in preconfigured shipping containers ready to be plugged in. I don’t mean the computers are ready to be plugged in, but the containers! What Microsoft then does is put a bunch of these containers close to a power plant (for obvious reasons), plug all the containers in and they’re up and running. At least that’s how it was described to me :-) The applications, services, data etc you have put into this cloud is distributed across many VM’s, meaning if a VM or server (hosting VM’s) goes down, it’s not a problem. There is always some VM on some server holding your data. Actually the shipping containers I mentioned are remotely managed and MS never enters any of these containers for maintenance. If a computer goes down and does not come up again, it just stays down. If this happens to a certain number of servers within one container, the whole container is disconnected from the grid and sent back to HP or Dell to be fixed, without affecting any of the applications or services! This little story told by Clemens Vasters really says a lot of the scale on this monster!

    Can I take my existing application and deploy it to the cloud using Azure Services Platform?

    The short answer is: no. The longer answer is: you might in the future. First of all the platform is still in Beta, but beside from that David Chappell says: “Azure Services Platform today targets the next Facebook”, meaning it’s highly scalable and can support a lot of users. To support this level of scalability there are some compromises to be made. On Azure this is (among other things) how you store and access data. Using a plain SQL server with relational tables and ADO.net would just not scale/perform. Thereby they decided to implement a different solution where the data are stored hierarchically and data is exposed via a RESTful interface using a LINQ like query language. Unless your application have this type of data implementation today, you would have to rewrite your data access and data layer. But don’t take my (or David’s) word for it, check out this video about table storage (which you would think is normal relational tables, but it’s not) from MS and you can make up your own mind: http://wm.microsoft.com/ms/msdn/azure/scalablestoragetables.wmv. Note though that in this video they’re using Windows Azure Storage and not SQL Services, but the same is true for SQL Services.

    If I can't deploy my existing app to Azure Services today, what CAN I do?

    The obvious thing is to wait and hope Microsoft will add support for relational tables allowing you to use existing SQL Server data implementations, but the Azure Services Platform is much more than a place to have your application and data. Your (local) application might want to interact with services in the cloud to enhance your existing application. I find the Service Bus to be especially interesting, or even the Access Control Service. This is only from my perspective and within the enterprise domain where I work. If you work with a more consumer oriented domain, you might find the Live Services interesting. Note that you don’t have to use the complete platform to make use of Azure Services. You can of course select the ones giving you value for you particular domain.

    What’s the difference between Microsoft SQL Services and Windows Azure Storage?

    First of all these two services looks very similar today and one might think why have both? My impression though is that Windows Azure Storage is going to remain much the same, but SQL Services are going to expand quite a bit (reporting, analytics, synchronization etc). Clemens offered this simplified analogy: “Think of Azure Storage as the registry on Windows, and think of SQL Services as your SQL Server.”. Another important difference is that Azure Storage is not built on existing SQL Server technology, but SQL Services is. Another interesting thing pointed out by David is that none of these services use SQL!? They use a RESTful interface with a LINQ like query language. He offered one explanation to this: SQL within MS means SQL Server :-)

    What’s the Access Control Service and is it limited to only Azure apps?

    The Access Control Service is “Microsoft’s humble attempt” to support as many access control providers as possible, so that this service will become a common place to perform identification. They state that “No one is willing to take this responsibility, so we have to” :-) Just think of it. How many providers of access control do we have today? Google, Microsoft, Amazon all have their own personal identity services on the internet. In addition there are a lot of others like Active Directory, Novell eDirectory, Apple Open Directory etc. What if this service would support the majority of these? Then you could use this service to do the access control for your system being in the cloud or not, and the end user could use his provider of choice. For more information about the Access Control Service check out the MSDN site: http://msdn.microsoft.com/en-gb/library/dd129876.aspx (note that this url might be quickly outdated).

    By choosing the Azure Services Platform, will I be locked in by that platform?

    By “locked in” I’m here going to assume you mean if you can move your cloud application away from this platform and on to another if you want to. Taking into account the current providers of cloud platforms we have today and the current services they provide, my impression is that you will be locked in. Just because of the simple fact that no one else is supporting .Net like Microsoft do. Hey, wait a minute… What if I use Amazon’s EC2 which gives me a Windows Server 2008 and a SQL Server, can’t I then move to that platform? That environment support .Net just fine. Well, it depends… :-) If you’re using the Azure Storage or SQL Services, you can’t cause it’s just not a plain SQL Server. It seams like the common thing to do among cloud services providers is to create their own data access solutions (or even programming languages like SaleForce.com have done), meaning you will be locked in on that. If you’re not using the data storage solutions you might not be.

    Why should I be afraid of being locked in anyway? I’ve already chosen Microsoft as my technology provider. Yea, but now you’re also locking onto your host. If your host (in this case MS) decides that the solution you’re running in their environment should be increased by a cost of 500% and you can’t afford that, what do you do? Find another cloud provider?

    However, one interesting thing to note about Azure Services Platform is what MS says about programming languages. They want (though they don’t do today) to support many other languages like Eclipse, Ruby, PHP and Python. Google only support Python, SalesForce only support their own language Apex, Amazon basically provide you with VM’s (Linux and Windows) leaving you to choose. Another interesting aspect is that MS seams to be very open about what and how they’re doing things. 

    People are talking about the Web Role and the Worker Role. What’s that all about?

    The Web Role and the Worker Role is part of the Windows Azure fabric (see separate section for more fabric info). Microsoft says:

    A web role is an ASP.NET web application that may be accessed via an HTTP or HTTPS endpoint. Web roles run in integrated pipeline mode on a hosted IIS7 web core. 
    ..and/or:
    A web role is a web application accessible via an HTTP and/or an HTTPS endpoint. A web role is hosted in an environment designed to support a subset of ASP.NET and Windows Communication Foundation technologies.

    A worker role is a background processing component. It does not accept inbound network connections.
    ..and/or:
    A worker role is a background processing application. A worker role may communicate with storage services and with other Internet-based services. It does not expose any external endpoints. A worker role can read requests from a queue defined in the Queue storage service.

    A service may consist of a single web role, a single worker role, or one of each.

    When you create Azure projects in Visual Studio, you select which Role you want your project to be (or both). As described above the main difference between the two is that the web role allow incoming traffic, while the the worker role does not.

    What’s “The Fabric”?

    The Fabric, or more accurately Windows Azure fabric, is the operating system that the services run on. Again from MS:

    The Windows Azure fabric offers an Internet-scale hosting environment built on geographically distributed data centers. This hosting environment provides a runtime execution environment for managed code. The fabric handles load balancing and resource management and automatically manages the life cycle of a service based on requirements established by the owner of the service. The developer includes with the service code specifications for the service topology, the number of instances to deploy, and any configuration settings. The fabric deploys the service and manages upgrades and failures to maintain availability.

    To try to simplify (in my words): Below the fabric you’ll find a lot of VM’s. On top of the fabric you’ll find Compute and Storage. The fabric host .Net and take care of networking stuff.

    What if I’m not going to build “The next FaceBook”, is this still something for me?

    Absolutely. Even though the architecture behind it all is built so that it can handle the next Facebook, it does not mean you can’t use it for an enterprise solution which have less than 1000 users or an application you want to share with your friends. It will be interesting though to see if MS will provide us with different data models, so that we don’t have to use a really scalable one, when we will never need it, also allowing us to port existing solutions onto their platform.

    What’s it going to cost?

    No one knows. At least not outside of Microsoft. We do however know some thoughts they have around the pricing model(s). It does not look like they’re going for a “simple” price model as e.g. Amazon which charge per hour. They will probably use a combination of CPU, network, storage and transactions(data) to calculate the price. More details can be found here: http://www.microsoft.com/azure/pricing.mspx (note that this url might quickly become outdated).

    Who else out there offer cloud services?

    According to David Chappell; Amazon, Google and SalesForce.com are the leading providers today. All of these provide different solutions and pricing models.

    Will everybody now deploy their apps to the cloud?

    Not now, but I defiantly see this as a very attractive hosting model in the future, and for some it is already today with services provided by e.g. Amazon. I would think it’s especially interesting for startups that does not have the resources (money and knowledge) to set up a datacenter for hosting their solution.

    Hi, this is your mom. Do I need to know what this is?

    No. You together with the rest of the world not running an IT company or doing programming can happily not care and just use whatever services that will be provided through this platform without you knowing. Btw mom, you don’t have to read my blog if you don’t want to ;-)

    Where’s Hello Cloud?

    It’s here: http://wm.microsoft.com/ms/msdn/azure/hellocloud.wmv
    ..and implemented here: http://hellocloud.cloudapp.net/

    Are any of the material from the sessions you attended made available for the public?

    You can find David Chappell’s presentation here: https://cid-88b5769d9bbdf846.skydrive.live.com/self.aspx/Offentlig/Azure%20Services%20Platform--Chappell.pdf

    Monday, December 15, 2008 12:50:37 AM (W. Europe Standard Time, UTC+01:00)
    Tuesday, November 25, 2008

    On the DDD mailing list a few days ago Richard Pawson posted that he and his team have created a DDD framework for .Net. Since I’ve had my head down in DDD for the last couple of months I thought I’d check it out. When posting this I’ve still not tried it, but I’ve watched some of the videos which you can find here:  http://www.nakedobjects.net/demo/demo_intro.shtml

    Honestly I’m not sure what I think of DDD frameworks in general. By definition I’m skeptical :-), but I promise to try it out and come back with some sort of conclusion of my findings and impressions. Btw. I’ve not been approached by Naked Objects to review their product in case you were wondering :)

    .Net | Architecture | DDD | Patterns | Software | Tools
    Tuesday, November 25, 2008 8:44:41 AM (W. Europe Standard Time, UTC+01:00)
    Friday, October 24, 2008

    This is my fourth post in my WiX and DTF series. Here are some others I’ve written:

    Intro

    In this article I’ll cover how to allow a user to choose which web site to install an application to by listing available web sites in a list box in the MSI installation wizard. As mention in my previous articles I'm applying best practices (at the best of my knowledge) to have the installer pass the Vista certification, so hopefully that will be the case if you use any of this in production :-)

    When doing lookups in IIS using custom actions in the InstallUISequence (as we need to do in order to get available web sites), elevated privileges is required (at least in Vista SP1). This means we need the installation to run as admin. This is also an issue in the WiX extension for IIS as described in this bug report. See my previous article of a workaround for both the UI Sequence part and the bug: Using a bootstrapper to force elevated privileges in Vista

    If you did not quite understand what I just said about the sequence stuff, elevated privileges etc., relax and keep reading, you will know by the end of this post and/or by clicking the link above :-)

    Overview

    This article assume you’ve read my previous article about Using WiX to author MSI installations or that you are somewhat familiar with WiX. If you haven’t done so already and want to follow this article step-by-step, download the WiX project from my previous article here: SimpleWebApp.zip

    There is another possibility of course :-) If you’re lazy and just want the complete source for this article, you can download everything from here: SimpleWebApp_WSSelect.zip

    Since this article became rather long I’ve structured it into 3 main sections with related sub sections, which hopefully will help you later if you need to look up something:

    Now let’s dig into it!

    Custom actions

    To add a CA to your solution, do this:

    1. Add a new class library project to your solution and name it IISCustomAction
    2. Add a reference to Microsoft.Deployment.WindowsInstaller found in the WiX SDK
    3. Add a reference to System.DirectoryServices
    4. Rename the class created by VS to CustomAction.cs
    5. Add the following using’s to CustomAction.cs:
      1. using System.DirectoryServices;
      2. using Microsoft.Deployment.WindowsInstaller;

    When building your project a couple of things happens:

    • The managed dll (IISCustomAction.dll) is created as expected by a class library
    • MakeSfxCA.exe (which is automatically called when building in VS) is creating a new dll based on the managed dll named IISCustomAction.CA.dll (this is the one you need to use in your WiX project)

    It’s MakeSfxCA.exe that does all the magic here. The output dll that MakeSfxCA has created is actually a Win32 DLL. Here’s what Christopher Painter says about this:

    At runtime, MSI thinks it’s calling a Win32 DLL in it’s own sandbox but in reality the CLR is being fired up out of process and communicated with through a named pipe.

    Read the complete article here.

    A typical CA looks something like this:

    [CustomAction]
    
    public static ActionResult MyCustomAction(Session session)
    
    {
    
        try
    
        {
    
            ...
    
        }
    
        catch (Exception ex)
    
        {
    
            session.Log("CustomActionException: " + ex.ToString());
    
            return ActionResult.Failure;
    
        }
    
        return ActionResult.Success;
    
    }

    The [CustomAction] attribute is needed to tag this method as a CA. The ActionResult returns either (in my case) Failure or Success allowing the installer to respond accordingly. The parameter for this method is a Session object. This object gives me access to the MSI database and the inner workings of Windows Installer allowing me to query the database, access MSI properties etc.

    Now you have what you need to start writing CA’s for the Windows Installer, so let’s get cranking.

    Custom action – Get web sites
    Copy and paste the code below into the CustomAction.cs class in the project you created above:

    [CustomAction]
    
    public static ActionResult GetWebSites(Session session)
    
    {
    
        try
    
        {
    
            View listBoxView = session.Database.OpenView("select * from ListBox");
    
            View availableWSView = session.Database.OpenView("select * from AvailableWebSites");
    
            DirectoryEntry iisRoot = new DirectoryEntry("IIS://localhost/W3SVC");
    
            int order = 1;
    
            foreach (DirectoryEntry webSite in iisRoot.Children)
    
            {
    
                if (webSite.SchemaClassName.ToLower() == "iiswebserver" && 
    
                    webSite.Name.ToLower() != "administration web site")
    
                {
    
                    StoreWebSiteDataInListBoxTable(webSite, order, listBoxView);
    
                    StoreWebSiteDataInAvailableWebSitesTable(webSite, availableWSView);
    
                    order++;
    
                }
    
            }
    
        }
    
        catch (Exception ex)
    
        {
    
            session.Log("CustomActionException: " + ex.ToString());
    
            return ActionResult.Failure;
    
        }
    
        return ActionResult.Success;
    
    }

    Here’s what I’ve done in the code above:

    • Open two views to the msi database. One for the ListBox table and one for a custom table which I will cover later called AvailableWebSites.
    • Get the root entry in IIS by using an LDAP query.
    • Iterate every child of the web site to get and store the information I need.

    Here’s the code for the two helper methods I use to store the IIS data to the Windows Installer database:

    private static void StoreWebSiteDataInListBoxTable(DirectoryEntry webSite, int order, View listBoxView)
    
    {
    
        Record newListBoxRecord = new Record(4);
    
        newListBoxRecord[1] = "WEBSITE";
    
        newListBoxRecord[2] = order;
    
        newListBoxRecord[3] = webSite.Name;
    
        newListBoxRecord[4] = webSite.Properties["ServerComment"].Value;
    
        listBoxView.Modify(ViewModifyMode.InsertTemporary, newListBoxRecord);
    
    }
    
    private static void StoreWebSiteDataInAvailableWebSitesTable(DirectoryEntry webSite, View availableWSView)
    
    {
    
        //Get Ip, Port and Header from server bindings
    
        string[] serverBindings = ((string)webSite.Properties["ServerBindings"].Value).Split(':');
    
        string ip = serverBindings[0];
    
        string port = serverBindings[1];
    
        string header = serverBindings[2];
    
        Record newFoundWebSiteRecord = new Record(5);
    
        newFoundWebSiteRecord[1] = webSite.Name;
    
        newFoundWebSiteRecord[2] = webSite.Properties["ServerComment"].Value;
    
        newFoundWebSiteRecord[3] = port;
    
        newFoundWebSiteRecord[4] = ip;
    
        newFoundWebSiteRecord[5] = header;
    
        availableWSView.Modify(ViewModifyMode.InsertTemporary, newFoundWebSiteRecord);
    
    }

    The first method stores data in the ListBox table and the second in my custom AvailableWebSites table.

    My custom table (which I’ll explain in more detail later) contains the following columns:

    • WebSiteNo
    • WebSiteDescription
    • WebSitePort
    • WebSiteIP
    • WebSiteHeader

    The ListBox table has these four columns:

    • Property
    • Order
    • Value
    • Text

    For the ListBox table the Property is used for identifying one specific list box and will allow you to get the Value of the selected item later. The Property must be the same for every record that you want displayed in one single UI list box. Order defines in which order the item are displayed in the list. Value is what’s being returned to you when accessing the property later on. The Text field is what is shown in the UI list box that the end user sees in the MSI wizard.

    In my code I set the Property for all records to WEBSITE. The Order is set to 1 the first time and then incremented by 1 every iteration. The Value is set to the web site id and theText is set to the web site name.

    After the user have selected the web site we can find out which one by using the WEBSITE property, which will give us the id of the web site (the Value field).

    In my custom AvailableWebSites table I store some more details about every web site. But before I can do that I need to get the server bindings from IIS which is formatted like this: ip:port:header. I split these up and add them to to the database. I do the same with WebSiteNo and WebSiteDescription.

    In both cases I store the values to the record and update the database (using modify). Note that you have to use InsertTemporary because you’re not allowed to write permanent data to the MSI database during installation.

    Custom action – Add selected web site info to properties
    After the user have selected a web site in the list box, I call a CA where I store the details about the web site to some public properties. This will make more sense later when we stitch everything together in the WiX product file, but for now here’s the code:

    [CustomAction]
    
    public static ActionResult UpdatePropsWithSelectedWebSite(Session session)
    
    {
    
        try
    
        {
    
            string selectedWebSiteId = session["WEBSITE"];
    
            session.Log("CA: Found web site id: " + selectedWebSiteId);
    
            View availableWebSitesView = session.Database.OpenView("Select * from AvailableWebSites where WebSiteNo=" + selectedWebSiteId);
    
            availableWebSitesView.Execute();
    
            Record record = availableWebSitesView.Fetch();
    
            if ((record[1].ToString()) == selectedWebSiteId)
    
            {
    
                session["WEBSITE_DESCRIPTION"] = (string)record[2];
    
                session["WEBSITE_PORT"] = (string)record[3];
    
                session["WEBSITE_IP"] = (string)record[4];
    
                session["WEBSITE_HEADER"] = (string)record[5];
    
            }
    
        }
    
        catch(Exception ex)
    
        {
    
            session.Log("CustomActionException: " + ex.ToString());
    
            return ActionResult.Failure;
    
        }
    
        return ActionResult.Success;
    
    }

    Remember the id for the web site that the user selected is stored in the WEBSITE property in the ListBox table? I can get this value by calling session[“WEBSITE”]. I then query my custom table that I populated earlier for details about this web site using Select with the id of the web site in the where clause. I then store these values to the properties: WEBSITE_DESCRIPTION, WEBSITE_PORT, WEBSITE_IP and WEBSITE_HEADER. These properties and where they came from will be explained later :-)

    Create a new dialog

    To have the user see and select from available web sites, we need to create a dialog displaying a list box. Add a new wxs file to your project and name it SelectWebSiteDlg.wxs. Then replace any generated xml with this xml:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    
      <Fragment>
    
        <CustomAction Id="UpdatePropsWithSelectedWebSite" BinaryKey="WebSiteCA" DllEntry="UpdatePropsWithSelectedWebSite" Execute="immediate" Return="check" />
    
        <Binary Id="WebSiteCA" SourceFile="$(var.SolutionDir)\IISCustomAction\bin\Debug\IISCustomAction.CA.dll" />
    
      </Fragment>
    
      <Fragment>
    
        <UI>
    
          <Dialog Id="SelectWebSiteDlg" Width="370" Height="270" Title="Select Web Site">
    
            <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.WixUINext)" />
    
            <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="!(loc.WixUIBack)" />
    
            <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.WixUICancel)">
    
              <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
    
            </Control>
    
            <Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes" Text="Please select which web site you want to install to." />
    
            <Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes" Text="Select Web Site" />
    
            <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="!(loc.InstallDirDlgBannerBitmap)" />
    
            <Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
    
            <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
    
            <Control Id="SelectWebSiteLabel" Type="Text" X="20" Y="60" Width="290" Height="14" NoPrefix="yes" Text="Select web site:" />
    
            <Control Id="SelectWebSiteCombo" Type="ListBox" X="20" Y="75" Width="200" Height="150" Property="WEBSITE" Sorted="yes" />
    
          </Dialog>
    
        </UI>
    
      </Fragment>
    
    </Wix>

    This xml file is separated into two fragments; one for the CA and one for the actual UI. The CA entry define in which assembly the CA is located and defines an id we can use later when calling the CA. This CA is the one I created previously for updating some properties with IIS data. The reason I’m defining it here is that I can, and it makes sense to group it with the dialog that are using it. Because, as you will see later, we’re going to call this CA after the user have clicked next on this dialog.

    The UI section is where the layout of the actual UI components is defined. Most elements are default for any dialog, except SelectWebSiteLabel and SelectWebSiteCombo which is the two controls specific to the web site dialog.

    I also need to update MyUI.wxs which controls which and in which order the dialogs are displayed in the wizard. I’ve added the SelectWebSiteDlg between InstallDirDlg and VerifyReadyDlg as shown here:

    <Publish Dialog="InstallDirDlg" Control="Next" Event="SetTargetPath" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
    
    <Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="WixUIValidatePath" Order="2">1</Publish>
    
    <Publish Dialog="InstallDirDlg" Control="Next" Event="SpawnDialog" Value="InvalidDirDlg" Order="3"><![CDATA[WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
    
    <Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog" Value="SelectWebSiteDlg" Order="6"><![CDATA[WIXUI_INSTALLDIR_VALID="1"]]></Publish>
    
    <Publish Dialog="InstallDirDlg" Control="ChangeFolder" Property="_BrowseProperty" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
    
    <Publish Dialog="InstallDirDlg" Control="ChangeFolder" Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>
    
    <Publish Dialog="SelectWebSiteDlg" Control="Next" Event="DoAction" Value="UpdatePropsWithSelectedWebSite" Order="1">1</Publish>
    
    <Publish Dialog="SelectWebSiteDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="2">1</Publish>
    
    <Publish Dialog="SelectWebSiteDlg" Control="Back" Event="NewDialog" Value="InstallDirDlg" Order="1">1</Publish>
    
    <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="SelectWebSiteDlg" Order="1">NOT Installed</Publish>
    
    <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="2">Installed</Publish>

    See that I use DoAction to call the CA I defined earlier? This is how you hook up a CA to the “click event” of a button (or any control for that matter). Not quite as easy as in Win Forms, but it’s still quite logical.

    Also note that I’ve changed the Next event for InstallDirDlg and the Back event for VerifyReadyDlg to point to my new dialog. This so the wizard will navigate correctly when the user clicks the next and back buttons.

    Changes to Product.wxs (the main WiX file)

    Custom Table – Storing web site info
    I promised to cover my custom table in more detail later, so here it is. First the code:

    <CustomTable Id="AvailableWebSites" >
    
      <Column Id="WebSiteNo" Category="Identifier" PrimaryKey="yes" Type="int" Width="4" />
    
      <Column Id="WebSiteDescription" Category="Text" Type="string" PrimaryKey="no"/>
    
      <Column Id="WebSitePort" Category="Text" Type="string" PrimaryKey="no"/>
    
      <Column Id="WebSiteIP" Category="Text" Type="string" PrimaryKey="no" Nullable="yes"/>
    
      <Column Id="WebSiteHeader" Category="Text" Type="string" PrimaryKey="no" Nullable="yes"/>
    
      <Row>
    
        <Data Column="WebSiteNo">0</Data>
    
        <Data Column="WebSiteDescription">Bogus</Data>
    
        <Data Column="WebSitePort">0</Data>
    
        <Data Column="WebSiteIP"></Data>
    
        <Data Column="WebSiteHeader"></Data>
    
      </Row>
    
    </CustomTable>

    When a user have selected the web site to install to, instead of querying IIS for details about the web site (web site number, description, port etc), I can just get it from my AvailableWebSite table. Note that I’ve added some dummy data in the first row. Without this the custom table was not stored to the MSI and I did not find any other way of getting this to work.

    Properties: Define, store and retrieve
    Earlier I created a CA that stored info about the selected web site into some public properties. Where did these properties come from? Well, they’re defined in the Product.wxs file like this:

    <Property Id="WEBSITE_DESCRIPTION">
    
      <RegistrySearch Id="WebSiteDescription"
    
              Name="WebSiteDescription"
    
              Root="HKLM"
    
              Key="SOFTWARE\torresdal.net\SimpleWebApp\Install"
    
              Type="raw" />
    
    </Property>
    
    <Property Id="WEBSITE_PORT">
    
      <RegistrySearch Id="WebSitePort"
    
              Name="WebSitePort"
    
              Root="HKLM"
    
              Key="SOFTWARE\torresdal.net\SimpleWebApp\Install"
    
              Type="raw" />
    
    </Property>
    
    <Property Id="WEBSITE_IP">
    
      <RegistrySearch Id="WebSiteIP"
    
              Name="WebSiteIP"
    
              Root="HKLM"
    
              Key="SOFTWARE\torresdal.net\SimpleWebApp\Install"
    
              Type="raw" />
    
    </Property>
    
    <Property Id="WEBSITE_HEADER">
    
      <RegistrySearch Id="WebSiteHeader"
    
              Name="WebSiteHeader"
    
              Root="HKLM"
    
              Key="SOFTWARE\torresdal.net\SimpleWebApp\Install"
    
              Type="raw" />
    
    </Property>

    I’ve also defined a registry search within each property. Why? In order to have access to these values during e.g. repair or uninstall we need to store them in the registry for later use. Why? Well, the Windows Installer does not maintain state (except from INSTALLDIR and maybe a few others). Meaning any values or selections a user did during installation is not kept for later use. Since we will need to know which web site the user installed the application to, so we can remove it on uninstall, we need to store the state to the registry. If the application has been installed before, the registry search above get’s these values from the registry and stores them in their respective properties.

    But how did they end up in the registry to begin with? I do that by defining a new component like this:

    <Component Id="PersistWebSiteValues" Guid="C3DAE2E2-FB49-48ba-ACB0-B2B5B726AE65">
    
      <RegistryKey Root="HKLM" Key="SOFTWARE\torresdal.net\SimpleWebApp\Install">
    
        <RegistryValue Name="WebSiteDescription" Type="string" Value="[WEBSITE_DESCRIPTION]"/>
    
        <RegistryValue Name="WebSitePort" Type="string" Value="[WEBSITE_PORT]"/>
    
        <RegistryValue Name="WebSiteIP" Type="string" Value="[WEBSITE_IP]"/>
    
        <RegistryValue Name="WebSiteHeader" Type="string" Value="[WEBSITE_HEADER]"/>
    
      </RegistryKey>
    
    </Component>

    And we need to reference the component under the Feature tag:

    <ComponentRef Id="PersistWebSiteValues" />

    Registry key’s in WiX require a component, which is good. That means that these keys/values will be added on install and removed on uninstall, saving us manual work. The registry key above is created at SOFTWARE\torresdal.net\SimpleWebApp\Install. The actual values are the properties as you see in the Value attributes. To reference a property just use [MY_PROPERTY]. This comes in handy many times when authoring MSI installations.

    Reference CA’s
    One of the CA’s (the UpdatePropsWithSelectedWebSite) is actually already referenced in the SelectWebSiteDlg, but we need to reference the GetWebSites CA as well:

    <CustomAction Id="GetIISWebSites" BinaryKey="IISCA" DllEntry="GetWebSites" Execute="immediate"  Return="check" />
    
    <Binary Id="IISCA" SourceFile="$(var.SolutionDir)IISCustomAction\bin\Debug\IISCustomAction.CA.dll" />
    

    The CustomAction tag defines a logical entry that we can use later to call this CA by using the id GetIISWebSites. In addition there is a Binary node that tells where WiX can find this CA when build the project. The CustomAction node point to this by using the BynaryKey attribute.

    Then we need to make sure it’s being called:

    <InstallUISequence>
    
      <Custom Action="GetIISWebSites" After="CostFinalize" Overridable="yes">NOT Installed</Custom>
    
    </InstallUISequence>

    The above code tells the installer to run this CA in the UISequence only when the application is not already installed (defined by the NOT Installed condition).

    Change the WebSite standard action
    In order for the installer to pick up the properties we’ve set for the selected web site (description, port, ip etc) we need to change the code we had previously:

    <iis:WebSite Id='DefaultWebSite' Description='Default Web Site'>
    
        <iis:WebAddress Id='AllUnassigned' Port='80' />
    
    </iis:WebSite>

    To this:

    <iis:WebSite Id="SelectedWebSite" Description="[WEBSITE_DESCRIPTION]">
    
      <iis:WebAddress Id="AllUnassigned" Port="[WEBSITE_PORT]" IP="[WEBSITE_IP]" Header="[WEBSITE_HEADER]" />
    
    </iis:WebSite>
    

    Makes sense right? I’ve also changed the id to SelectedWebSite which is more accurate in this case, meaning you need to update the WebSite reference in WebVirtualDir in the IISAppplication component as well. If you fail to do this the WiX compiler will complain, so you’re in safe hands :-)

    The complete Product.wxs
    There’s a lot of snippets above, so for your convenience I’ve included the complete code for Product.wxs here so you see everything together:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension" xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension">
    
      <Product Id="77da05c4-1644-4bc3-ac14-c0f721fe31fe" Name="Simple Web App" Language="1033" Version="1.0.0.0" Manufacturer="Jon Torresdal" UpgradeCode="a897ccc5-1c81-47e0-a837-65c07a72a7bc">
    
        <Package InstallerVersion="400" Compressed="yes" />
    
        <Media Id="1" Cabinet="WixProject1.cab" EmbedCab="yes" />
    
        <Property Id="TARGETVDIR" Value="SimpleWebApp"/>
    
        <Property Id="WEBSITE_DESCRIPTION">
    
          <RegistrySearch Id="WebSiteDescription"
    
                  Name="WebSiteDescription"
    
                  Root="HKLM"
    
                  Key="SOFTWARE\torresdal.net\SimpleWebApp\Install"
    
                  Type="raw" />
    
        </Property>
    
        <Property Id="WEBSITE_PORT">
    
          <RegistrySearch Id="WebSitePort"
    
                  Name="WebSitePort"
    
                  Root="HKLM"
    
                  Key="SOFTWARE\torresdal.net\SimpleWebApp\Install"
    
                  Type="raw" />
    
        </Property>
    
        <Property Id="WEBSITE_IP">
    
          <RegistrySearch Id="WebSiteIP"
    
                  Name="WebSiteIP"
    
                  Root="HKLM"
    
                  Key="SOFTWARE\torresdal.net\SimpleWebApp\Install"
    
                  Type="raw" />
    
        </Property>
    
        <Property Id="WEBSITE_HEADER">
    
          <RegistrySearch Id="WebSiteHeader"
    
                  Name="WebSiteHeader"
    
                  Root="HKLM"
    
                  Key="SOFTWARE\torresdal.net\SimpleWebApp\Install"
    
                  Type="raw" />
    
        </Property>
    
        <CustomAction Id="GetIISWebSites" BinaryKey="IISCA" DllEntry="GetWebSites" Execute="immediate"  Return="check" />
    
        <Binary Id="IISCA" SourceFile="$(var.SolutionDir)IISCustomAction\bin\Debug\IISCustomAction.CA.dll" />
    
        <InstallUISequence>
    
          <Custom Action="GetIISWebSites" After="CostFinalize" Overridable="yes">NOT Installed</Custom>
    
        </InstallUISequence>
    
        <Directory Id="TARGETDIR" Name="SourceDir">
    
          <Directory Id="ProgramFilesFolder">
    
            <Directory Id="INSTALLLOCATION" Name="SimpleWebApp">
    
              <Component Id="Default.aspx" Guid="fc46b1a2-35e9-4a17-896b-80b2daaae567">
    
                <File Id="Default.aspx" Name="Default.aspx" Source="$(var.SolutionDir)SimpleWebApp\Default.aspx" DiskId="1" KeyPath="yes" />
    
              </Component>
    
              <Component Id="Web.config" Guid="2ED81B77-F153-4003-9006-4770D789D4B6">
    
                <File Id="Web.config" Name="Web.config" Source="$(var.SolutionDir)SimpleWebApp\Web.config" DiskId="1" KeyPath="yes" />
    
                <util:XmlFile Id="AppSettingsAddNode" File="[INSTALLLOCATION]Web.config" Action="createElement" ElementPath="/configuration/appSettings" Name="add" Sequence="1" />
    
                <util:XmlFile Id="AppSettingsKeyAttribute" Action="setValue" File="[INSTALLLOCATION]Web.config" ElementPath="/configuration/appSettings/add" Name="key" Value="AddedDuringInstall" Sequence="2" />
    
                <util:XmlFile Id="AppSettingsValueAttribute" Action="setValue" File="[INSTALLLOCATION]Web.config" ElementPath="/configuration/appSettings/add" Name="value" Value="This text was added during installation." Sequence="3" />
    
              </Component>
    
              <Directory Id="binFolder" Name="bin">
    
                <Component Id="SimpleWebApp.dll" Guid="7FC6DA37-12E5-463d-8E7E-08F73E40CCF2">
    
                  <File Id="SimpleWebApp.dll" Name="SimpleWebApp.dll" Source="$(var.SolutionDir)SimpleWebApp\Bin\SimpleWebApp.dll" DiskId="1" KeyPath="yes" />
    
                </Component>
    
              </Directory>
    
            </Directory>
    
          </Directory>
    
          <Directory Id="ProgramMenuFolder">
    
            <Directory Id="MyWebAppStartMenuFolder" Name="SimpleWebApp">
    
              <Component Id="StartMenuFolder" Guid="B3AEC4C4-3F8E-4865-B87A-B750533776B5" >
    
                <util:InternetShortcut Id="SimpleWebAppShortcut" Name="SimpleWebApp" Target="http://localhost/SimpleWebApp/Default.aspx" Directory="MyWebAppStartMenuFolder" />
    
                <RemoveFolder Id="RemoveStartMenuFolder1" On="uninstall"/>
    
                <RegistryKey Root="HKCU" Key="SOFTWARE\torresdal.net\SimpleWebApp\SimpleWebAppShortcut">
    
                  <RegistryValue Type="string" Value="Default Value"/>
    
                </RegistryKey>
    
              </Component>
    
            </Directory>
    
          </Directory>
    
          <Component Id="IISApplication" Guid="FFA12D9C-5AEC-45f8-AA7D-5C4CEC7FA466">
    
            <iis:WebAppPool Id="SWAAppPool" Name="SWAAppPool" />
    
            <iis:WebVirtualDir Id="VirtualDir" Alias="[TARGETVDIR]" Directory="INSTALLLOCATION" WebSite="SelectedWebSite">
    
              <iis:WebApplication Id="SimpleWebAppApp" Name="[TARGETVDIR]" WebAppPool="SWAAppPool" />
    
              <iis:WebDirProperties Id="WebVirtualDirProperties" Execute="yes" Script="yes" Read="yes" WindowsAuthentication="no" AnonymousAccess="yes" IIsControlledPassword="yes" />
    
            </iis:WebVirtualDir>
    
          </Component>
    
          <Component Id="PersistWebSiteValues" Guid="C3DAE2E2-FB49-48ba-ACB0-B2B5B726AE65">
    
            <RegistryKey Root="HKLM" Key="SOFTWARE\torresdal.net\SimpleWebApp\Install">
    
              <RegistryValue Name="WebSiteDescription" Type="string" Value="[WEBSITE_DESCRIPTION]"/>
    
              <RegistryValue Name="WebSitePort" Type="string" Value="[WEBSITE_PORT]"/>
    
              <RegistryValue Name="WebSiteIP" Type="string" Value="[WEBSITE_IP]"/>
    
              <RegistryValue Name="WebSiteHeader" Type="string" Value="[WEBSITE_HEADER]"/>
    
            </RegistryKey>
    
          </Component>
    
        </Directory>
    
        <CustomTable Id="AvailableWebSites" >
    
          <Column Id="WebSiteNo" Category="Identifier" PrimaryKey="yes" Type="int" Width="4" />
    
          <Column Id="WebSiteDescription" Category="Text" Type="string" PrimaryKey="no"/>
    
          <Column Id="WebSitePort" Category="Text" Type="string" PrimaryKey="no"/>
    
          <Column Id="WebSiteIP" Category="Text" Type="string" PrimaryKey="no" Nullable="yes"/>
    
          <Column Id="WebSiteHeader" Category="Text" Type="string" PrimaryKey="no" Nullable="yes"/>
    
          <Row>
    
            <Data Column="WebSiteNo">0</Data>
    
            <Data Column="WebSiteDescription">Bogus</Data>
    
            <Data Column="WebSitePort">0</Data>
    
            <Data Column="WebSiteIP"></Data>
    
            <Data Column="WebSiteHeader"></Data>
    
          </Row>
    
        </CustomTable>
    
        <iis:WebSite Id="SelectedWebSite" Description="[WEBSITE_DESCRIPTION]">
    
          <iis:WebAddress Id="AllUnassigned" Port="[WEBSITE_PORT]" IP="[WEBSITE_IP]" Header="[WEBSITE_HEADER]" />
    
        </iis:WebSite>
    
        <Property Id="WIXUI_INSTALLDIR" Value="INSTALLLOCATION" />
    
        <UIRef Id="MyUI" />
    
        <Feature Id="ProductFeature" Title="SimpleWebApp" Level="1">
    
          <ComponentRef Id="Default.aspx" />
    
          <ComponentRef Id="Web.config" />
    
          <ComponentRef Id="SimpleWebApp.dll" />
    
          <ComponentRef Id="StartMenuFolder" />
    
          <ComponentRef Id="IISApplication" />
    
          <ComponentRef Id="PersistWebSiteValues" />
    
        </Feature>
    
      </Product>
    
    </Wix>
    

    The End! 
    That’s that! If you’ve come this far you (hopefully) have a functional CA with goodies that allow your user to select web sites in your installer. Hope you found this post useful and let me know if you find any errors or questions, and I’ll help you out. Btw here’s the end result:

    MsiSelectWebSite

    .Net | CSharp | Deployment | IIS | WiX
    Friday, October 24, 2008 10:41:23 PM (W. Europe Daylight Time, UTC+02:00)
    Saturday, October 11, 2008

    WixVS Earlier this week I posted a question on the WiX user list. The question was: Which version of WiX is being distributed with Visual Studio 2010?

    As you probably know by know (at least if your interested in msi and deployment) is that WiX will ship as part of Visual Studio 2010. To make a long story short, the answer is 3.0. This was expected, but I was still curious. Having WiX v. 3.0 with VS means that all developers have the option to create advanced installations using Windows Installer, and also to create Custom Actions (CA’s) in managed code!

    Saturday, October 11, 2008 12:33:05 AM (W. Europe Daylight Time, UTC+02:00)
    Monday, October 06, 2008

    This is my third post in my WiX and DTF series for WiX 3.0. Here are some others I’ve written:

    Normally bootstrappers are used for adding prerequisites to your installation; like the .Net Framework, Windows Installer etc. You can also use it for other purposes though. Basically it's an exe file with the msi (and any other installers) embedded. For the WiX series I'm currently doing we need this because:

    1. Use as workaround for the WiX bug in IIS extension where the installer fails because of missing privileges on Vista SP1.
    2. We want to do IIS custom actions in InstallUISequence which require elevated privileges which I will cover in a later post (hopefully very soon!).

    I briefly mentioned InstallUISequence above. Windows Installer have several sequences, for details you can check them out here, but I'm just going to shortly explain two of them now. The InstallUISequence is the wizard part in the installer, InstallExecuteSequence is where things are happening and files are getting installed (when you click "Install" in the wizard).

    Here's a bit of background. In Vista msi files does not run elevated (as admin) when you start them directly (double click on the msi). To do that you need to open an elevated command prompt and run the msi with msiexec /i yourInstaller.msi. That's not a good solution.

    Normally there should be no need for admin privileges in UISequence (it's a reason it's not permitted per default), but there are exceptions, like the above. At least from my perspective. If you have a better way of solving this, I'm very interested.

    So, with a bootstrapper or exe file you can do a bit more. For instance you can use mt.exe to add a manifest to he exe defining which privileges it requires to run. In this article I will describe how you can accomplish this using WiX and .Net.

    Here's how to go about it:

    1. Copy Setup.exe found in the WiX bin folder to your project location (so we don't modify the original)
    2. Create a manifest file (e.g. Vista.manifest) in your favorite text editor by adding this xml:
      <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
      
      <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
      
        <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="Setup" type="win32" />
      
        <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
      
          <security>
      
            <requestedPrivileges>
      
              <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
      
            </requestedPrivileges>
      
          </security>
      
        </trustInfo>
      
      </assembly>
    3. Add the manifest to Setup.exe by using mt.exe found in the .Net SDK:

      mt.exe -manifest [pathToYourProject\]Vista.manifest -outputresource:[pathToYourProject\]Setup.exe;#1

    4. Use setupbld.exe found in the WiX bin folder to embed the msi installer into a exe like this:

      setupbld.exe" -out Setup.exe -msu MyMsi.msi -setup Setup.exe

      or even better, add it as a post-build event (Right click your project -> Properties -> Build Event -> Post-build Event Command Line):

      "C:\Program Files\Windows Installer XML v3\bin\setupbld.exe" -out $(TargetDir)Setup.exe -msu "$(TargetPath)" -setup "$(ProjectDir)setup.exe"

    The interesting thing to note about the manifest file is this:

    <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

    When setting the level to requireAdministrator Vista will show a UAC prompt when executing this file. The default level is asInvoker, which will run the exe with the current users privileges, but then the exe would have the same behavior as the msi.

    Also note the assemblyIdentity node where you can set the actual version number of your installer and the name (if you use something else than Setup.exe).

    .Net | Deployment | Security | Vista | WiX
    Monday, October 06, 2008 12:47:02 PM (W. Europe Daylight Time, UTC+02:00)
    Thursday, September 04, 2008

    This is my first post in my WiX and DTF series for WiX 3.0. Here are some others I’ve written:

    Windows Installer XML (WiX)

    The version of WiX I'm going to talk about is v.3.0, currently in beta. In essence WiX is an XML format for writing MSI deployment packages. Much like using InstallShield or Wise to write your installations, you can use WiX to do the same. So why do you want to use XML to author your msi's? At first I thought: "Ohhh no! Not another XML based authoring tool!" But after doing some more digging, this is one of the scenarios were XML makes sense... kind of. Here's the benefits I see with WiX compared to traditional MSI tools:

    • It's perfect for "code" generation, using Nant, TFS etc.
    • WiX is very clean, so it gives you the possibility to author exactly what you need and not have all the general stuff that IS and Wise has pre added to your installation

    Another thing to note is that WiX is open source and it comes from Microsoft (yea, Microsoft HAVE open source projects). Not only that, but this tool got so popular within Microsoft that most of their packages are now moving towards using WiX, and many of them, like Office, already use WiX. That says a lot!

    I'll get back to using WiX to author msi installations in a later post, but now I want to focus on DTF and how to use it without WiX.

    Deployment Tools Foundation (DTF)

    DTF is among other things a managed (.net) wrapper on top of msi.dll (the windows installer library). DTF makes it possible to write custom actions (CA's) for MSI installations in C#, VB.net or any other .Net language. If you're not used to working with MSI installations this might not be a big deal for you, but for me this is fantastic news! Not only that, debugging has now become much easier (or should i say possible).

    Before you only had three options for writing CA's: C++, VB Script and Java Script. CA's are custom code you write because there are currently no existing action supported by MS Installer that does what you're looking for.

    Examples of things you can do with Windows Installer out of the box are:

    • Install/delete/move files
    • Create/delete/change folders
    • Create/delete/change shortcuts
    • Install/remove/start/stop Windows Services
    • Reboots
    • Install/remove ODBC drivers
    • Register/un-register COM/COM+ applications
    • Register/un-register fonts
    • Write/change registry
    • ...and so on...

    Check this out for a more complete list.

    However, Windows Installer can't cover all scenarios, so then you turn to CA's. Here are some examples I've used CA's for:

    • List SQL Servers
    • List IIS Web Sites
    • Create Web Sites and Virtual Directories
    • Change XML files

    You should however know this; writing good CA's is difficult and there is a lot of things to take into account. For instance, what happens if your installation fails and starts rolling back? Then you need to make sure that any changes you've done to the system with your CA also needs to roll back, meaning you have to have two CA's, one for adding stuff and one for removing stuff.

    Why not just stick to VB/Java script?

    Using VB and Java scripts has become more and more difficult because of security restrictions, virus programs etc. Many virus programs will not allow you to use Windows Scripting Host (WSH) at all.

    About 2 months ago I did some work on our existing msi packages related to a Microsoft certification program. The requirements for this certification forced me to adopt the best practices that I should have done a long time ago. To avoid the problem with scripting I had two options. Rewrite my CA's in C++, or in C# using DTF. After digging around it was an easy choice. I went for managed code.

    However, this might not be the right solution for you. Managed code require the .Net framework, so if you don't know if .Net is present on the computer running your software, you might want to stick to "traditional" CA's. For me this was not a problem, since all computers (clients and servers) we install on already have .Net pre-installed.

    Next

    Next time I'll show you how to create a CA for listing available IIS Web Sites on IIS7. This will allow you to choose which web site to install your application under. Until then I suggest you check out WiX/DTF and start thinking if this is something for you.

    .Net | Deployment | Tools | WiX
    Thursday, September 04, 2008 12:29:31 AM (W. Europe Daylight Time, UTC+02:00)
    Tuesday, September 02, 2008

    As mentioned before, I created a small tool for sending out emails to our members in NNUG. When implementing tools like these I always make sure to experiment with new language features, patterns or similar. This time it was the fluent interface to be tested.

    Recently there has been a lot of focus on Domain Specific Languages (DSL's). A Fluent Interface is a specific type of DSL. Martin Fowler and Eric Evans gave this DSL type its name in 2005 which you can read more about here.

    To jump right into the usage of my interface here's how to send an email to one person from code:

    EmailComponent email = Email
        .To("somebody@torresdal.net")
        .From("anybody@torresdal.net")
        .WithSubject("Anybody out there?")
        .Using.Body("Guess not...");
    email.Send();

    The above code is nice, but you can't really do anything useful with it. You can send emails from code, but I would rather use an email client for that :-) So lets make it a bit more interesting:

    EmailComponent email = Email
        .ToAllIn("recipients.txt")
        .From("anybody@torresdal.net")
        .WithSubject("Anybody out there?")
        .Using.TxtBodyFromFile("someTxtFile.txt")
        .Using.HtmlBodyFromFile("someHtmlFile.html");
    email.Send();

    Now instead of specifying one single to address we point to a file where all the recipients are found. Also instead of the body text we use a text file and a html file to be used as the email body. In this way, when you send emails, people that can only receive plain text emails will get that, and the others will get the html version. This is done using the AlternateView class in .Net.

    But there is more interesting stuff you can do:

    EmailComponent email = Email
        .ToAllIn("recipients.txt")
        .From("anybody@torresdal.net")
        .WithSubject("Anybody out there?")
        .Using.TxtBodyFromFile("someTxtFile.txt")
        .Using.HtmlBodyFromFile("someHtmlFile.html")
        .PauseAfter.Every(30).EmailSent.For(20).Minutes;
    email.Send();

    In the last line we say: Pause after every 30 email sent for 20 minutes. So what would you use that for? If you send out 500 emails, your smtp server might not like you very much, so he/she just reject your request thinking you're a spammer. By splitting it up you still might be a spammer, but the smtp server won't know it.

    There are many variants of the above line. Here's a few other examples:

    .PauseAfter.Every(10).Minutes.For(1).Hour;
    .PauseAfter.Every().Hour.For(2).Hours

    How is this done you might ask? First of I read Anders Norås excellent article about fluent interfaces (Behind the scenes of the planning DSL) and Martin Fowler's articles from his coming book about DSL's to get a deeper understanding.

    So in essence I've basically picked the right words (hopefully) for the method names and properties to build up an understandable sentence implemented by using Method Chaining. Here's what Martin Fowler says about method chaining:

    Method Chaining is an idiom that acheives this through a sequence of modifier calls where each call returns the host object for further modification.

    Implementing method chaining is quite simple illustrated by the code below:

    public Email To(string emailAddress)
    {
        _to = emailAddress;
        return this;
    }

    This is from my Email class of the fluent interface. See how it returns itself? This is so that you can do subsequent calls to the same class.

    If you've been very observant you've seen that the To method returns an Email object, but the object type returned after the "sentence" is finished is an EmailComponent. As Anders accurately describe in his post this is done using an implicit user-defined type conversion operator in C#. It's actually not as difficult as it might sound :-) Check out Anders article for details.

    Another good point made by Anders is writing this without "code by example" or TDD is almost impossible. Write your sentences first and then implement the code. Actually, for people trying to learn/master TDD an excellent way of practicing is writing a fluent interface!

    Even though this was really cool (at least I think so), is it any useful? If you see where fluent interfaces are used today, they tend to be around configuration. Instead of hacking around in an xml file not really knowing when you miss type something, using a type safe fluent interface might be a good idea. Examples of this is Ninject, NHibernate and others. Is my Email client any good as a fluent interface? If you remove the PauseAfter functionality the answer is: not really. However, the PauseAfter thing actually adds some value to it all. There are other ways of solving that quite nice just using a plain API, but that's no fun is it?! :-)

    .Net | CSharp | DSL | Patterns
    Tuesday, September 02, 2008 7:57:23 PM (W. Europe Daylight Time, UTC+02:00)
    Friday, August 08, 2008

    A couple of days ago I discovered a bug in Hotmail that you can read about here.  As it turns out it was both a bug in Hotmail and in my code (sort of), and a type error in my blog post causing some confusion. Thanks to Rune Grothaug for getting me in touch with the Hotmail team.

    The bug in Hotmail is related to how they query for content id's in the email. It's too expensive to load the email into a html parser to get the id's, so they do a string match instead. Here's how I understand it:  When they try to match nnug10 they actually get nnug1 back (as the first match). One solution suggested by them was to reverse the order of the searches allowing nnug10 to be found first. I'm not sure if this is what they're going to do. (Update: I got confirmation that this is the solution they're going for)

    As for my bug it was that I forgot to add the file extension to the ContentType.Name (see code below). This is the name that actually gets displayed for the attachment image in the mail. In Hotmail (and Gmail for that matter) it shows all linked resources as attachments, and the name of these attachments had no extensions (e.g. jpg). A workaround for the Hotmail bug could have been to do the same with the ContentId. When the id is nnug10.jpg it actually works! In my blog post I said that the cid's where nnug0.jpg, nnug1.jpg etc. which was not the case. It did not have the .jpg extensions.

    Taking the above into account this makes the Hotmail bug far less serious than I originally thought.

    But..., when you see the property ContentId you're thinking it can be whatever only it's unique right? This is why I didn't think much of what the ContentId was as long as it was unique. However, to be absolutely sure that something like this will not happen again I changed the cid's to be guid's instead (this was also suggested by the Hotmail team). Better safe than sorry :-)

    Here's the code after my modifications:

    LinkedResource img = new LinkedResource(stream, mediaType);
    img.ContentId = guid;
    img.ContentType.MediaType = mediaType;
    img.TransferEncoding = TransferEncoding.Base64;
    img.ContentType.Name = img.ContentId + fileExtension;
    img.ContentLink = new Uri("cid:" + img.ContentId);
    resources.Add(img);
    Friday, August 08, 2008 9:30:42 PM (W. Europe Daylight Time, UTC+02:00)
    Thursday, August 07, 2008

    Update: More on this story here.

    I've been playing around with an email tool that I've created to send out emails to NNUG members. It's just a simple command line tool sending an email to each person in a list to avoid using bcc which sometimes get hooked in a spam filter. Another thing this tool does is to take an html page (an html formatted email), scan it for images and embed the images using the AlternateView class and its LinkedResources collection for sending as an html email.

    The emails sent by this tool looked ok in Outlook, Gmail and Hotmail on every test I did. Except for when I decided to use the tool to send out an official NNUG invitation to 300 members! The only change I had done was adding one extra image. I noticed that the email I got on my Hotmail account had a wrong image at the end. The image used was the same as the second image in the email. The reason was not hard to find.

    When I add images to the LinkedResources collection, I name the images/files nnug[someNumber].jpg like this:

    nnug0.jpg, nnug1.jpg, nnug2.jpg etc.

    This worked fine for all images up to nnug10.jpg. Can you see why nnug10.jpg did not work and what the bug is? The last image that was supposed to be nnug10 was showing up as the second image instead (nnug1). E.g. nnug10 = nnug1! Hmmm.... Come on!

    Then my apology. To all members of NNUG with a registered Hotmail account and to Christian Weyer:

    I'm sorry that I did not discover this bug before, so I could have changed my algorithm. Sorry to you Christian for being nnug1.jpg! You replaced the NNUG logo, resulting in the email ending with:

      Kind regards [image of Christian]

    instead of

      Kind regards (image of NNUG logo)

    ...giving the email a bit different meaning than I intended :-)

    Btw. don't forget to sign up for the NNUG events by Christian Weyer and Dan North 25th and 27th August!

    .Net | Fun | Microsoft | NNUG
    Thursday, August 07, 2008 1:43:23 AM (W. Europe Daylight Time, UTC+02:00)
    Tuesday, May 27, 2008

    Brian Harry over at the TFS team has a great post about the new features that will be available in the coming SP1 for TFS 2008.

    Tuesday, May 27, 2008 7:47:50 AM (W. Europe Daylight Time, UTC+02:00)
    Saturday, May 24, 2008

    Pex Earlier this month Fredrik Normén wrote a post about argument validation. Yesterday Rune Grothaug from MS Norway posted a link to a new tool MS has developed in their research lab called Pex (Program EXploration). Combining these two (argument validation and Pex) have to be a perfect match.

    .Net | Testing | Tools
    Saturday, May 24, 2008 11:31:09 PM (W. Europe Daylight Time, UTC+02:00)
    Tuesday, May 13, 2008

    Update: This article is not limited to deploying applications to Vista, but also when changing files that are only writeable by administrators (e.g. files in the Program Files directory).

    If you have not made specific changes to your installation to support UAC in Vista, this is for you. I hope this will help others to not spend many days of confusion, desperation and sleepless nights like I have.

    Lately I've been getting reports from some of my coworkers running Windows Vista that the app.config file in our application was not updated after installation. I've also experienced this myself. We've solved them without knowing exactly how (which I hate). Typically "I uninstalled the application and installed to a different location, and it worked!" Well, this is a workaround that are not particulary popular to any of our customers, so I dived into the problem to find the exact reason.

    To save you some reading I'll just say that the reason and solution is to provide your application with a manifest file to handle UAC in Vista as described in this article: Create and Embed an Application Manifest (UAC) I haven't actually tried this out yet, but I trust the article to be correct :-)

    Virtualization
    But that's not the interesting part. The interesting part is what happens (or what can happen) if you don't have an application manifest for this purpose? If your superstitious you might think that something weird is going on with your computer. If you're like me you KNOW that something weird is going on with your computer, and you need to find it and fix it. The weird thing is Vista virtualization.

    "File virtualization addresses the situation where an application relies on the ability to store a file, such as a configuration file, in a system location typically writeable only by administrators"

    "Virtualization is implemented to improve application compatibility problems for applications running as a standard user on Windows Vista."

    As I write this I have exactly this problem on my computer. I've installed our application (Contiki ECM) to this location: C:\Program Files\CMA Contiki AS\Contiki ECM\. This is where I've always install our app. So today I installed and checked that the app.config was updated with all my changes done during installation. And it hadn't. Actually it was updated, but not with my changes. It looked like an old file that I had some time ago. How could this happen?

    Textpad .vs. Notepad
    To make this even more confusing, I discovered this reading the file in TextPad, but when opening the file in Notepad it was fine. All my changes was there! So I thought that this was a TextPad problem. I started our application, but it turns out that when .Net tries to read the config file, it reads the same old stuff as TextPad did, resulting in old config to be loaded into our app. Why does Notepad get the right file? I don't know. Please tell me if you do.

    The solution
    So after Googling for a while I found this article on MSDN, and things started to make sense. But first let me show you what it looks like on my computer. The file causing my headaches are Contiki.Windows.Application.exe.config.

    VistaUNCImg1 
    Do you see when it's modified? 08:56 this morning, but the file that is being opened is from 13th of April! How do I know? Well, if you have a look at the virtualized files which you'll find in C:\Users\Username\AppData\Local\VirtualStore\[Your path], it might help out. So I looked at C:\Users\1jontor\AppData\Local\VirtualStore\Program Files\CMA Contiki AS\Contiki ECM and found this:

    VistaUNCImg2 
    Modified back in April. I opened this file and it was exactly what I saw in TextPad. But this file is the same both in TextPad and Notepad! :-)

    Explorer gives you a shortcut to the Virtual Store folder if any files are virtualized, and will show this button in Explorer:

    VistaUNCImg3

    The end
    A couple of notes from the MSDN article:

    "When you enumerate resources in folders and in the registry, Windows Vista will merge global file/folder and registry keys into a single list. In this merged view, the global (protected) resource is listed along with the virtualized resource."

    "The virtual copy will always be present to the application first.... even if [some file] is updated"

    Even if the file is updated!? Who though of that? Was that really such a good idea? I can see what they where thinking, but it would have saved me a lot of work getting an error message saying "Access denied"...

    To end this off I picked another good quote from the article:

    "Microsoft intends to remove virtualization from future versions of the Windows operating system as more applications are migrated to Windows Vista."

    I appreciate that... :-)

    Tuesday, May 13, 2008 10:08:42 PM (W. Europe Daylight Time, UTC+02:00)
    Friday, April 11, 2008

    The first .Net user group ever (as far as I could find out) was started by Ruth Walther in Seattle December 2000. It seams like this group is no longer active and I was unable to find out why. Anyway, today you'll find a user group in almost every major city in any country. And if you don't have a user group where you live, I think it's about time you start one! :-) Seriously, it's not that hard and you'll be a hero where you live! :-)  I can really recommend the experience and people will defiantly appreciate someone taking the first step to get your city on the user group map.

    NNUG2After the first user group started up in the US many others soon followed during 2001. To pick a few other countries I'm familiar with I can say that my home country Norway started their first user group in Oslo October 2001 and in my city Bergen we started up in December 2002, the London .Net User Group was started in 2002 and Sydney Australia in April 2002, .

    It's free
    HangingDollars Most user groups I know of don't charge for membership. Many don't even have memberships, but use the word of the people to announce their meeting or that "everybody" knows that their having a meeting last Wednesday in every month, and it's just to show up. User groups rely on local, national and/or international sponsorship. If your country have a Microsoft company present, they usually help out. This can be to help you get in touch with speakers, sponsor travel costs (for speakers), pizza and the like. The user group I run in Bergen use local sponsors for pizza, but get some help from Microsoft for travel costs. When requesting speakers it's often smart to provide them with consulting when they visit your city. This is a nice way of helping your local companies get excellent consulting and it make the speakers trip to your city a bit more attractive.

    Why are user groups so popular?
    There are many reasons for this and they vary from user group to user group. But from my experience there are some general things that should more or less apply to all user groups:

    • It's free
    • You get free food (usually pizza)
    • You get to meet other people from other companies to share experience with, that you would usually not meet outside the user group
    • You learn a lot
    • Keeps you up to date on what's going on
    • Communities in general are popular

    INETA
    Ineta INETA is the mother organization for all .Net user groups. Its an acronym short for International .NET Association. You will find user group related to SQL server, VB, SharePoint and other .Net related products. They all have in common that they focus on some type of Microsoft .Net related technology. INETA is divided into five geographical areas; North America, Latin America, Middle East and Africa, Asia Pacific and Europe. My experience is with INETA Europe, but I expect it to work much the same in the rest of the world. INETA Europe have among other things a Speaker Bureau with lots of good speakers. As a member your user group can request two speakers per year. These are top notch speakers! In Europe you'll see names like Ingo Rammer, Christian Weyer, Dino Esposito to mention a few. As a member your user group will also get a quarterly kit where you can select some books, cd's and other stuff to use as giveaways for you members, prizes etc. INETA also helps getting user groups started, especially if it's the first user group in the country. If there are existing groups in the country, the other groups usually helps you getting started in your city. That's how communities work!

    .Net | Microsoft | NNUG
    Friday, April 11, 2008 4:03:52 PM (W. Europe Daylight Time, UTC+02:00)
    Thursday, March 13, 2008

    MouseClickServer deployment of ClickOnce? Isn't ClickOnce client deployment? Yes, it is. However, you will have to deploy the ClickOnce files to a server, right? I feel this is a poorly documented step and I thought I share some of my experience around this.

    So what's the problem? The main issue is the deployment manifest file. If you've worked with ClickOnce you know about this file, if not here's a (very) short description. The deployment manifest includes information about where the ClickOnce application is located (e.g. http://myServer/myWD/myApp.application) as showed in the following snippet:



    ...
    <
    deployment install="true"
    mapFileExtensions="true"
    trustURLParameters="true"> <subscription> <update> <beforeApplicationStartup /> </update> </subscription> <deploymentProvider
    codebase="http://myServer/myWD/myApp.application"
    /> </deployment>
    ...

    This file needs to be signed with a certificate to be valid, which means that any changes to this file makes it invalid and you'll have to resign it. This is a good thing for security, but it causes some problems regarding deployment. The url specified in this file must be changed when deployed at a server. Unless you want to get all information needed from your customer and create the deployment package before sending it to them or force them to set up a server named myServer ;-). I don't think that solution is very likely to be used in production systems. So what you need to do, is make the installation (e.g. msi) change the manifest file and resign it during installation.

    Microsoft has provided us with a tool to do exactly this. However, you're not allowed to redistribute it. Another issue is that you need to have a certificate for signing and you don't want to have your corporate certificate laying around in your msi. The most common solution around this problem is to prompt the user during installation for a certificate (like suggested here). But then your app is signed by someone else's certificate, which is probably not what you want.

    I will now suggest a different solution to this problem. In the System.Build.Tasks.dll you'll find much of the functionality needed to do the same thing as Microsoft's Mage.exe is doing. The nice thing about this dll is that it's a part of the default .Net Framework installation. Here's a short description of the classes needed:

    DeployManifest
    An object model for the manifest file. Gives you direct access to specific parts of the manifest and makes it really easy to make changes.

    ManifestReader
    Have a static method (ReadManifest) which let you read and return the manifest you are going to work with.

    ManifestWriter
    Use the static method WriteManifest to write your changes back to the manifest file.

    X509Certificate2
    Your certificate to sign the manifest file with.

    SecurityUtiities
    Has the static method called SignFile which let you sign your manifest.

    By using the classes described above it should be quite easy to achieve the same as with the Microsoft utility. Here's an example:

    using System;
    using System.IO;
    using System.Reflection;
    using System.Security.Cryptography.X509Certificates;
    using Microsoft.Build.Tasks.Deployment.ManifestUtilities;
    ...
    string
    manifestPath = @"C:\Temp\myApp.application"; string deploymentUrl = "http://myServer/myWD/myApp.application"; DeployManifest manifest =
    (DeployManifest)ManifestReader.
    ReadManifest("DeployManifest", manifestPath, false); manifest.DeploymentUrl = deploymentUrl; ManifestWriter.WriteManifest(manifest); X509Certificate2 certificate =
    new
    X509Certificate2(GetCertificateFile(), "password"); SecurityUtilities.SignFile(certificate, null, manifestPath);

    There is one important step we need to solve. How do we protect the certificate we need to sign the manifest file. For this I suggest you incorporate this into your tool (either a command line tool or a .Net library) by using Build Action = Embedded Resource. This will make your certificate inaccessible for most people. If you want to secure it even more, you can crypt it in however way you want. I leave this up to you ;-) In my code above I've done this in the GetcertificateFile() method:

    X509Certificate2 certificate = 
    new
    X509Certificate2(GetCertificateFile(), "password");

    There is of course one other issue which you'll have to consider. What if someone uses your custom tool to sign their ClickOnce app? So you need to protect this as well with a password or some other mechanism. If you have a good suggestion to this, please let me know.

    Thursday, March 13, 2008 3:03:15 PM (W. Europe Standard Time, UTC+01:00)
    Tuesday, February 26, 2008

    You might argue both, but that's beyond the point :-) I've been thinking lately about how different programmers get their work done. If you look over the shoulders to 3 programmers, none of them is working the same way. The first difference I tend to notice is the use of keyboard shortcuts. Personally I've always been a fan of shortcuts, especially in development environments like Visual Studio, but also general shortcuts in Windows or other applications. For instance I never do File -> Open. I always use ctrl -> O and it always annoys me when a program does not support the most common shortcuts. However, I still feel I can learn and use more of them.

    We can divide developers into three groups related to the above:

    1. Love the mouse and rarely use shortcuts
    2. Use mouse often, but use shortcuts for the most common actions
    3. Use the mouse only when there's no shortcut for the action.

    I think I can put myself in category 2 and I'm not sure if I want to or are able to be in category 3. One important aspect to consider before I dig myself to deep into this, is that you don't necessarily produce better software by using a lots of shortcuts (obviously). However I'm quite sure that a developer in group 3 produce code faster than a group 1 developer. But one can argue (if you're a bit extreme) that the quality of the code produced by group 1 is better, because they get more time to think :-) But seriously you can't use this type of groupings for defining developers, but in general I think many developers could benefit from using more shortcuts.

    Here are the most common shortcuts in Visual Studio 2005 as I see it:

    Builds    
    Ctrl+B, Ctrl+S Build BuildSelection
    Ctrl+Shift+B Build BuildSolution
    Ctrl+Break Build Cancel
         
    Debugging    
    F5 Debug Start
    Ctrl+F5 Debug StartWithoutDebugging
    Shift+F5 Debug StopDebugging
    F10 Debug StepOver
    F11 Debug StepInto
    Ctrl+F10 Debug RunToCursor
    Shift+F11 Debug StepOut
    Ctrl+Shift+F10 Debug SetNextStatement
    F9 Debug ToggleBreakpoint
    Ctrl+Shift+F9 Debug DeleteAllBreakpoints
         
    Navigation    
    F12 Edit GoToDefinition
    Ctrl+F12 Edit GoToDeclaration
         
    Other    
    Shift+Alt+Enter View FullScreen
    Ctrl+Shift+F12 View NextError
    Ctrl+Alt+P Tools AttachtoProcess
    Shift+Alt+A Project AddExistingItem
    Ctrl+K, Ctrl+M Edit GenerateMethodStub

    You probably know where and how already, but if you go to Tools -> Options -> Keyboard in Visual Studio you can define your own shortcuts. This is a great feature of Visual Studio that let you create custom shortcuts for almost every action you can do with a mouse. You can either change an existing shortcut or define new ones. Here's a screenshot of the shortcut dialog in VS:

    image

    Commands are displayed alphabetically after some type of menu structure (e.g. Edit.Copy), though there a many more commands than you can find in the menu. This list is of course populated dynamically which means you'll find commands for 3rd party VS plugins like e.g. ReSharper. One thing to be aware of though is existing shortcuts. If you for instance want to have the shortcut Ctrl+V, Ctrl+A, you will override the Ctrl+V command for Paste, which is probably not what you want.

    Tuesday, February 26, 2008 2:53:51 AM (W. Europe Standard Time, UTC+01:00)
    Tuesday, February 12, 2008

    NNUG_JavaBin The 27th of February Anders Norås will come and have two presentations on Domain Specific Languages (DSL). First we only planned one, but when I asked Anders if the presentation would be strictly .Net he suggested having two presentations, one on .Net and one on Java :) I thought this was a great opportunity to get the two local communities in Bergen together under the same roof. Sometimes there is sessions that is not directly connected to a technology platform and these types of presentations are great for joining forces and share experiences. Hopefully NNUG will visit JavaBin next time something like this comes around.

    I will post more info about the sessions later and if you're a member of NNUG you will get the meeting invitation shortly. The same goes for JavaBin members.

    Really looking forward to this and I hope to see you there.

    .Net | Events | Java | NNUG
    Tuesday, February 12, 2008 10:39:29 AM (W. Europe Standard Time, UTC+01:00)
    Friday, February 08, 2008

    Update: I've found a temporary solution. After inspecting which files was in our package I found a 3rd party component that we don't use anymore but still had a reference to. This was references by our business layer, which all our web services use, hence this dll was in every bin folder on every web service. Since the size of the file was quite big it was enough to get the installation down to a reasonable size and avoiding the described error message.

    For a while now our msi file that contains the application server for our product has not been working. Not an msi that our customers have, but one we're about to ship in two weeks. I've had my hands full for a long time, but today I finally got around to check what was causing the problem. Here's a screen shot of the error I get:

    MsiInstallError

    After a quick Google search I found that this is related to a bug on Windows Server 2003 and Windows XP. Cause:

    This problem occurs if the Windows Installer process has insufficient contiguous virtual memory to verify that the .msi package or the .msp package is correctly signed. 

    Fantastic! I will not go and ask all our customers to install the hotfix on their servers. That's just to stupid. About now you're probably thinking something like "How big is their app-server really?" or "What product can get to big for an msi file?". I can tell you... The size of the msi is 576MB. No images, no database, just pure .Net dll's! And actually we're not alone. Visual Studio Service Pack 1 had the exact same problem! Go figure. And even better, there is no hotfix for this on Windows XP.

    Have we been coding like mad men for a decade and producing tons of code? I wish (or maybe not) :) The answer is simpler than you might think. Our application server contains web services only. At the beginning of our project we took an architectural decision to have our web services separated in virtual directories (or projects in VS). This to be able to update parts of our application without affecting the whole system. This was part of a master plan around the smart client principle and would let us deploy small modules into our application which dynamically loads the new behavior. As it turns out we have almost never done this in production. The drawback of this is of course that you get many of the same dll's scattered around in many virtual directories. And when you have many web services (by web services I mean asmx files and not web methods, 43 to be exact), and each one is dependent on your business and data access layer (which is quite huge) and more, megabytes is piling up.

    So what's the solution? Well, since we don't really use this as intended we can just merge our web services into one and we will be home free. Except you don't do that two weeks before deployment with acceptance testing coming up. So I have to think of something else. The only solution I can see now is to find some way of making the msi smaller, which at the current time I don't have the faintest idea of how to accomplish. I can use a setup launcher (exe) which will probably solve it, but that will not make our customers very happy. Hopefully I'll figure something out during the weekend, or maybe you have a solution?

    Friday, February 08, 2008 10:37:08 PM (W. Europe Standard Time, UTC+01:00)
    Saturday, February 02, 2008
    Mark 17th and 18th of July June (Programutvikling's event site mention both June and July, but June is the correct month) in your calendar. Microsoft Norway and Programutvikling has managed to attract some great names. Check this out: Scott Hanselman, Roy Osherove, David Chappell, Mats Torgersen, Rafael Lukawiecki and Mary Poppendieck! Is that a great line-up or what? I wonder if they got this idea from my Developer Conference in Bergen post? ;)

    For now there's not much information out there, but you'll definitely hear more the coming months. Rune Grothaug's blog from the Microsoft DPE team is a great source for events in Norway. Programutvikling has the event on their site here.
    Saturday, February 02, 2008 12:22:49 AM (W. Europe Standard Time, UTC+01:00)
    Thursday, January 31, 2008
    NNUGPizza at NNUGIn my previous post about Developer conference in Bergen I said some not so nice things about the .Net community in Bergen (also called criticism). After today's meeting I take it all back. Everybody that showed up today proved me wrong. On previous meetings we were satisfied if 20 people showed up. Actually 20 people is/was our goal for average attendance for 2008. So what happened today? 43 people showed up to see Erik Leivestad and Thomas Eyde talk about Agile Project Management and Test Driven Development! For a time there I was worried that we didn't have seats for everybody. I really hope that this is the new norm at NNUG Bergen and not just a onetime incident.

    Erik LeivestadWe also did a quick survey before we started the meeting. We asked how many project managers and how many developers was in the audience. To my surprise almost everybody was developers. I was thinking that because of the Agile PM talk we might have attracted a different type of crowd than we usually do, but that was not the case.

    Thomas EydeThe second question was how many was here for the first time. About 50% of the crowd raised their hand. This was not a surprise for me since I checked the statistics the day before, but it's nice to get it confirmed :)

    The last question was how many will come to the next meeting, and that was depressing. The response was 3-4 hands at best. I guess you where thinking: "let’s have this meeting first and see how it goes" :)

    A big thank you to everybody that showed up today and a special thanks to Erik and Thomas for spending their spare time to educate us about agile processes and tools. It's really awarding to see a big crowd showing up when you've spent a lot of time (without getting paid) getting speakers and subjects that you hope people will like and find interesting. Finally I hope to see you on our next meeting the 27th of February. Until then, happy coding!

    .Net | Agile | Events | NNUG | Scrum
    Thursday, January 31, 2008 12:38:13 AM (W. Europe Standard Time, UTC+01:00)
    Friday, December 21, 2007

    During my involvement in NNUG I've been playing with the thought of having a developer conference in Bergen. Funny enough I first started to consider this when we had some problems getting people to come to our NNUG events. I couldn't figure out why Bergen had such a low participation when other (smaller) cities in Norway managed quite good. I've also got reports from Microsoft saying that MSDN Live didn't do to well in Bergen either. Is this just how it is in Bergen? We just don't want to get our hands on new knowledge? Or is there so much info on the web that we don't see the need for meeting up in person? Maybe Bergen is just the worst city in Norway to be a developer? We just go to work to get our paycheck and don't really want to be bothered with updating our knowledge unless forced to? I don't think so and sure don't hope so! My impression is that the Java community in Bergen does not have the same challenges.

    We will of course always have Mort though (see Jeff's articles here and here). Maybe Bergen is just overloaded with Morts? ;) However, I think a dev conference in Bergen has something to offer him as well.

    So why do I want a dev conference in a city where developers don't participate in their local .Net community? First of all it's because I don't think the above is true. I think there is a lot of great developers and companies in Bergen working with development that would both see the benefit and be proud to host a dev conf in their city. Second, I think NNUG will benefit greatly from this and raise the visibility around the .Net community in the city. Thirdly, I have too much free time on my hand so I'm looking for something to do in my spare time (kidding).

    So what do you think my dear reader? Is there room for a dev conference in Bergen? Would you come? And even better, would you volunteer to make this a reality? I'm volunteering now, but I need some helpers... :)

    You might state that we already have a developer conference in Bergen and you would be right. It's called Roots, but I'm thinking about a different kind of conference. Roots is an international niche conference around OO (Recent Object Oriented Trends), but I want a general Norwegian (Nordic) dev conf. Even though I'm a .Net guy and would like .Net tracks, I also think there is room for Java and agile tracks.

    And to all of you who have been going to NNUG regularly I apologize. The criticism in this post is to everyone except you ;)

    .Net | Events | NNUG
    Friday, December 21, 2007 12:47:35 PM (W. Europe Standard Time, UTC+01:00)
    Monday, November 05, 2007
    VSOrcas.gifThe wait is almost over. At TechEd Barcelona Microsoft announced the release date of Visual Studio 2008 and .Net Framework 3.5. Check out the official press release here: http://www.microsoft.com/presspass/press/2007/nov07/11-05TechEdDevelopersPR.mspx

    .Net | Events | TechEd | Tools | VisualStudio
    Monday, November 05, 2007 11:36:07 PM (W. Europe Standard Time, UTC+01:00)
    Sunday, August 19, 2007
    If you are like me you probably have a hard time finding something to create when trying out new stuff.  This time I sat down and tried to figure out something to use LINQ and Silverlight for and maybe WCF, WPF and Ajax as well. At the time I was watching TV and the EPG (Electronic Programming Guide) didn’t work, so I started to look for a web site with a program guide supporting reminders and other nice features to let you know what’s on TV. I didn’t find anything good.
    I then started to look for an xml/text format for TV programs. I did some searching and came across xmltv. Nice! I now had an xml source looking something like this:

    <tv>
      <channel id="channel1">    
        <
    display-name lang="nb">Channel 1</display-name>
      </channel>
      <channel id="channel2">
        <display-name lang="en">Channel 2</display-name>
      </channel>
      ...
      <programme start="20070801033000 +0200" stop="20070801053000 +0200" channel="channel1">
        <title lang="nb">Program 1</title>
        <desc lang="nb">Program description.</desc>
        <credits>
          <director>...</director>
          <actor>...</actor>
          <actor>...</actor>
        </credits>
        <date>2004</date>
        <category lang="en">movie</category>
        <category lang="en">drama</category>
      </programme>
      ...
    </tv>

    So now I had an xml document containing all the data I needed and this was a perfect time to try out XLINQ. I decided to stick with the LINQ query syntax and not mix in Lambda expressions to keep things simple and readable. I came up with this expression to get all TV channels:
    public List<TvChannel> GetTvChannelsWithoutGuide()
    {
    IEnumerable<TvChannel> channels; try
    { XElement tvGuide = XElement.Load(_xmlFileLoc);

    channels = from c in tvGuide.Descendants("channel")
    orderby (string)c.Element("display-name")
    ascending
    select new TvChannel
    {
    Id = (string)c.Attribute("id"),
    Name = (string)c.Element("display-name"),
    Lang = (string)c.Element("display-name")
    .Attribute("lang"),
    TvGuideLoaded = false
    };
    } catch (FileNotFoundException fileNotFoundEx) { throw new FileNotFoundException(
    string
    .Format("Xml file for tv guide not found at {0}",
    _xmlFileLoc), fileNotFoundEx); } return channels.ToList<TvChannel>(); }

    The XElement gives me the complete xml document that I can use XLINQ expressions on. In my query I’m looking only for TV channels, so I specify that in the query by

        from c in tvGuide.Descendants("channel")

    This gives my a variable c that I use in my orderby clause and select statement. The orderby clause

        orderby (string)c.Element("display-name") ascending


    uses the c variable to access the “display-name” element to set order by. But it’s the select statement which is the cool thing here! First here a listing of the TvChannel class:
    [Serializable]
    public class TvChannel {
    public string Id { get; set; } public string Name { get; set; } public string Lang { get; set; }

    [XmlIgnore]
    public IEnumerable<TvProgramme> TvGuideNonSerializable { get { return TvGuide; } set { TvGuide = value.ToList(); } }

    public List<TvProgramme> TvGuide
    { get; set; } public bool TvGuideLoaded { get; set; } } 
    Ignore the TvGuideNonSerializable property for now. By using select new TvChannel I can create an object of my TvChannel class an assign data from the xml document to my properties. I just love this syntax! It’s really nice and easally understandable. Another cool feature (running VS 2008 Beta 2) is that you get ItelliSense in LINQ for your classes, like this:

    LinqIntellisence.png

    I also created other methods for retrieving all programs for one channel, all channels etc. At the time of writing I’m working on a Silverlight implementation for the TvGuide which I hopefully can show you soon. And later I’ll make all source code available.

    .Net | CSharp | Linq | TvGuide | VisualStudio
    Sunday, August 19, 2007 1:11:51 PM (W. Europe Daylight Time, UTC+02:00)
    Tuesday, August 14, 2007
    TheDotNetShow.jpgJust saw that there was a new episode (Silverlight) of The .Net Show out, and it started with telling us that this is the last episode! I've been watching this show on and off since its startup in December 1999! The show has been running for almost 8 years which makes this the longest running series at Microsoft. However, all good things have to come to an end. But it’s sad. I’ve really enjoyed this show and for a time (before blogging and rss) it was one of my few sources to new .Net technology inside the walls of Microsoft. Robert Hess’s (the host) last words in the show were:
    Well, until next time, we'll see you on the Web and I might recommend you check out channel9.msdn.com. You never know who you might see show up there.
    So I guess this isn’t the last time we see Robert. Thanks for all your hard work on this show during the years, giving us the latest news and insight into .Net technology! Salute!

    Tuesday, August 14, 2007 10:55:54 AM (W. Europe Daylight Time, UTC+02:00)
    Saturday, August 11, 2007
    Christian Weyer has an article on MSDN Mag together with Steve Maine and Dominick Baier about using Windows Process Activation Service (WAS) for non http protocols. Actually it's about much more than that, but that is what I found interesting. Hosting WCF services in WAS gives you the possibility to use NetTcp, Named Pipes and MSMQ protocols. For more info about WAS you should read the article. Anyway, using WAS as a host for WCF services sounds like a good idea. You don't have to create and maintain your own NT Service and you get stuff like "on-demand activation, process health monitoring, enterprise-class manageability and rapid failure protection" for free. But then you also get some lifetime management "features":

    "...WAS does demand activation (as you know, the "A" in "WAS" stands for activation). This means that the application domain hosting a service only gets created when a request message comes in. Application domains shut down again after a configurable idle period. There are also several reasons why WAS or the ASP.NET runtime may decide to recycle the application domain or even the whole worker process."
    So I suspect there would be some overhead of creating and shutting down the app domain, unless you can set the idle period to infinite of course. And then you have the recycle bit... Hmmm.... Do I want that?

    If I were asked: "WAS or NT Service?", I think I'll go for the NT Service, unless there's something I totally missed out on here... which definitely could be the case <smile>.

    If you want to try this out you might find these code samples interesting in addition to the article mentioned.
    .Net | IIS | WCF
    Saturday, August 11, 2007 1:46:31 AM (W. Europe Daylight Time, UTC+02:00)
    Friday, July 27, 2007

    unicode.pngAt least we had. One of our customers reported a strange error in one of our web app’s running .Net 2.0. They got an error message after calling a web service (running on .Net 1.1) in the web app (.Net 2.0) and we just couldn’t figure it out.  We and our customer started to investigate and our customer found that after uninstalling the Security Update for .Net 2.0 (KB928365) things started to work again! Nice work customer!

    We started to investigate what caused the problem and found that one week ago we had found an error related to parsing Unicode. The problem is related to how the framework (or rather UTF8Encoding class) handles invalid bytes (see KB940521), only we didn't know that at the time. Here’s the short version of the KB article:

    …the behavior of the UTF8Encoding class, the UnicodeEncoding class, and the UTF32Encoding class changes to comply with the Unicode 5.0 requirements for Unicode encodings. Invalid bytes are not removed. Instead, the invalid bytes are replaced by the Unicode character U+FFFD.

    We had an invalid byte in the beginning of one of our xml documents that we manually created and returned as a string using UTF8Encoding. Don’t ask why we parse it to string; its old code that we haven’t replaced with XmlNode yet. Since this is now (in 2.0 with security update) replaced as a Unicode character it uses more space and we had to remove more bytes. Since this class was written in .Net 1.1 but is also used in 2.0, we made a quick fix for checking which framework and change the behavior accordingly. The KB articles states:

    Earlier versions of the .NET Framework 2.0 followed the latest available Unicode standard, Unicode 4.1. The specifications for Unicode 4.1 disallowed the passing of invalid UTF code points. Any invalid data that was encountered was dropped. This behavior was considered to have minimal effect on current programs.

    And then:

    Before this change, invalid characters in the middle of text strings would be silently removed. For example, the string "Ad\xD800min\xDC00istrator" would change to "Administrator" because the Unicode characters U+D800 and U+DC00 are invalid. This could cause a security problem for some programs. After you install security bulletin MS07-040, this string now becomes "Ad\xFFFDmin\xFFFDistrator." This string is decoded to "Ad�min�istrator," where the � is the Unicode replacement character.

     So if you have the same “bad” code or are using Unicode encodings with invalid bytes somewhere you might experience the same problem and hopefully this would be of help.

    Friday, July 27, 2007 3:21:43 PM (W. Europe Daylight Time, UTC+02:00)
    Wednesday, July 04, 2007
    ComPlus.jpgEver been annoyed by not being able to find the real object behind System.__ComObject? There is a solution and guess what; it's VB.Net (or at least the VB API)! Carlos has a how-to article that explains the solution. In essence you just have to have a reference (if you're running C# or a non VB language) to Microsoft.VisualBasic.dll. You can then use Microsoft.VisualBasic.Information.TypeName(someObject) to get the info you want. Thanks to Pablo Galiano for his blog post on this.

    .Net | CSharp
    Wednesday, July 04, 2007 10:47:07 AM (W. Europe Daylight Time, UTC+02:00)
    Sunday, May 20, 2007

    Update: PDC 07 is postponed! Check out http://msdn2.microsoft.com/en-us/events/bb288534.aspx, which will announce the new date when it’s ready.

    One of the highlights of the year for me is going to a devcon (developer conference). People I work with have asked me if I could recommend any events this year, so I wrote down the ones I knew about and googled for some others. Here’s the list I came up with:

    • MEDC 2007 (Berlin June 25-26 (Mobile & Embedded))
    • DDD5 (Reading, UK (1 day free event by the UK developer community groups) June 30)

    There are defiantly more events out there, but these were the ones I found in 5 minutes. Hopefully one of these events will be of interest for you. Enjoy!

    .Net | Events | TechEd
    Sunday, May 20, 2007 12:46:02 PM (W. Europe Daylight Time, UTC+02:00)
    Sunday, April 22, 2007
    VSOrcas.gifBeta 1 is now available and you'll find it here: http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx. I think you'll either need a MSDN subscription to get it or Virtual PC (you can download the Orcas vpc image here). Enjoy!

    Sunday, April 22, 2007 9:43:19 AM (W. Europe Daylight Time, UTC+02:00)
    Monday, March 12, 2007

    You've probably all seen this already, since you read Scott Guthrie’s blog as well (or that you’ve been on the internet after 2005), but he just posted a few examples of some of the new features in the C# Orcas framework. I can't wait to start using the automatic properties! I don’t know how many hours I’ve spent writing stupid get/set properties that only do one thing, return a private field.

    You might argue that it was about time some of these features got implemented or that they (MS) are just stealing from other languages. To be honest I don’t care as long as the language gets better and more productive to use.

    If you want to see the “complete” spec for C# features, you can check out this document: http://download.microsoft.com/download/5/8/6/5868081c-68aa-40de-9a45-a3803d8134b8/csharp_3.0_specification.doc

    .Net | CSharp
    Monday, March 12, 2007 12:19:11 AM (W. Europe Standard Time, UTC+01:00)
    Monday, January 22, 2007
    The guys at Microsoft Patterns & Practices have created a new site for upcoming releases. Nice to see what’s going on release wise. Take a look at Tom Hollanders blog to get the complete story.
    Monday, January 22, 2007 3:15:26 PM (W. Europe Standard Time, UTC+01:00)
    Friday, January 12, 2007
    NNUG.jpgI’m now officially the new leader of Norwegian .Net User Group in Bergen. I’d like to give Jon Andreas Bygstad great thanks for his excellent work and making NNUG in Bergen possible. And also for retire from his position to make room for me. Just kidding.

    Even though Jon Andreas decided not to have the main responsibility anymore, he will still be on the board participating like before. I have a lot to learn and will depend on his experience to be able to make NNUG in Bergen even better than it is today. I think NNUG’s future looks very promising and I hope you as a developer, architect, student or whatever position you have know how to take advantage of NNUG. We work hard to give you free updates on technology, speakers and pizza every month. So if you’re not a member of NNUG yet, go register now! Did I say it was FREE?!!

    If you'd like to participate, that being demo something you think is cool or try how it feels to be a speaker, we will be glad to hear from you. Our main goal is to make our .Net community in Bergen learn from each other by participating with subjects that is of interest to others. Also if you have any suggestions to how NNUG can be better, tell us about it! Go here to send us an email
    .Net | NNUG
    Friday, January 12, 2007 6:03:20 PM (W. Europe Standard Time, UTC+01:00)
    Wednesday, January 10, 2007
    Everyone who knows me knows that I have a special interest for memory leaks in .Net. At the company where I work we have solved a lot of these issues and I’ve also had talks about this at Norwegian .Net User Group (NNUG) in Bergen and Stavanger. One of our biggest problems was memory leaks related to events. Rico Mariani (MS performance guru) has set focus on this in his blog today by this blog post, so go check it out!

    He focuses on the issue related to event generators, but there are other areas where you can get into trouble as well. I’ll try to explain our scenario:
    1. We have a graphical engine responsible for creating graphical components (user controls) dynamically by using reflection.
    2. All of these user controls inherit from the same class which exposes a lot of events.
    3. When our graphical engine creates new instances of these user controls it hooks up these events.
    This model is created to have loose coupling between the user controls, the engine and other components we have in our app. The engine has a lot of knowledge about other components and services in our app, which sometimes our user controls wants to communicate with. This communication is done through these events. Here’s an example:
    I have a user control that wants to tell a service that he have made some changes the service should know about. For this we have created a special event on the user control that the engine listens to. So I trigger this event on the user control, the engine receives it and tells the service about it.
    com.png

    These event hookups caused us a lot of pain at some point. Our solution was the first that Rico mentioned in his blog post (IDisposable), which I personally would prefer. In addition to this we added some reflection code which found events and removed them. You’ll find more info about this here: http://channel9vip.orcsweb.com/ShowPost.aspx?PostID=180985

    Before I end I want to recommend two tools you can use to find memory leaks in .net. The first one which we use is called .Net Memory Profiler. The other one which I’ve not personally used but I’ve heard others are using is the ANTS Profiler. So go find your leaks. Happy hunting!
    .Net | MemoryLeaks | Microsoft | NNUG | Work
    Wednesday, January 10, 2007 1:02:22 AM (W. Europe Standard Time, UTC+01:00)
    Thursday, January 04, 2007
    At work at the moment I’m trying to calculate the migration complexity of our software from .net framework 1.1 to 3.0, with main focus on WCF. Specifically I’ve been doing some test migration of web services to WCF and regenerating our DTO’s to support data contracts. During this test migration an interesting issue came up. With our “old” web services we did our own serialization of DTO’s. Several reasons for that, which I’m not going into now, but this was a bit problematic in WCF at first. I’ll show you a quick example of a typical web service at my company:

    [WebMethod]
    public XmlNode GetSomeData() {
        return StaticBusiness.GetSomeData().Serialize2XmlNode();
    }

    In the example I just do a call to a static business method called GetSomeData. The return value from this method (which is one of our DTO’s) is then serialized to an XmlNode by calling Serialize2XmlNode().

    In WCF we do not want to handle serialization by our self, so we want WCF to take care of this for us and choose the best serialization mechanism available. So our service in WCF would look something like this:

    [ServiceContract()]
    public interface IMyService {
        [OperationContract]
        SomeDataObject GetSomeData();
    }

    public SomeDataObject GetSomeData() {
        return StaticBusiness.GetSomeData();
    }

    One of the reasons why we did our own serialization in 1.1 was lack of xml serialization support for circular references, but in WCF this is no longer an issue.

    So as long as my SomeDataObject  has a data contract it will be serialized and returned to the caller. As you probably have guessed we also de-serialized our DTO’s on the client side (since we returned an XmlNode), but that is now of course handled by WCF. Since we did our own serialization we were not dependent on proxy generation of our DTO’s and we could just reuse the dll on the client side. In our case we had .net on both sides so this was ok. In 1.1 we did it like this:

    return SomeDataObject.DeSerialize(MyWebService.GetSomeData());

    So I was trying to find a simple way of doing this in WCF. The solution was much simpler than I’d ever expected. By manually generating the proxy and using the /r parameter I was able to bypass proxy serialization of DTO’s. Fantastic!

    So a typical call to svcutil would look like this:

    svcutil /nologo /out:Proxy.cs /r:C:\Test\DTOs.dll /config:App.config /namespace:*,MyProxies net.tcp://localhost:9000/MyService/tcpmex


    This gives me a proxy called Proxy.cs and with my method looking like this:

    public DTOs.SomeDataObject GetSomeData
    {
        return base.Channel.GetSomeData();
    }


    This solved a great challenge for us. My next task at hand is to do some performance testing and see if we get the desired performance improvements by using NetTcp as appose to POWS (Plain Old Web Service).

    Thanks to Rick Strahl for his great blogpost on this subject.
    .Net | WCF
    Thursday, January 04, 2007 12:34:29 AM (W. Europe Standard Time, UTC+01:00)
    Friday, December 15, 2006
    During the day I found two new releases. Asp.net Ajax RC is out (http://ajax.asp.net/) and Visual Studio 2005 SP1 is released (http://msdn.microsoft.com/vstudio/support/vs2005sp1/default.aspx). I vote for Monday releases, so we can get paid testing them. Since I can’t keep my hands off these two, my weekend is ruined! :) Enjoy!

    Update: You might want to have a look at Scott Guthrie’s blog before running the installation. He has some tips you should have a look at. Both for pre Vista and Vista operation systems. You'll find his post on vs sp1 here and vista here.
    .Net | Ajax | Web | VisualStudio
    Friday, December 15, 2006 1:00:00 AM (W. Europe Standard Time, UTC+01:00)
    There has been a lot of confusion around web2.0. Who’s better to reduce this confusion than Martin Fowler! Check out his latest blog post about this topic. I especially found this interesting:

    "A common misconception I run into is that Web 2.0 is all new stuff. Most of the ideas under Web 2.0 are actually quite old and have been used on the web from early on, for instance Amazon's community or the use of Wikis. The point is that then they were the minority. The Web 2.0 shift is about the principles that were used by a few in the 90's becoming the majority in the future."

    And just to clarify even further, Web 2.0 is not a product; you cannot buy it in any store! :)
    .Net | Ajax | Web
    Friday, December 15, 2006 1:00:00 AM (W. Europe Standard Time, UTC+01:00)
    Thursday, December 14, 2006
    I love finding new cool feature rich 3rd party components that give my apps great look and feel. During the past six years I’ve tried a bunch of them. Back when I was a consultant this was a breeze. Find a component, pay for it, problem solved. But now when I’m working for an ISV and actually have to maintain the software we build, we suddenly came across this huge problem (or challenge for the consultants out there).

    We have two packages from two of the most famous .Net component vendors out there. We bought these about 3 years ago and come to think of it, it’s no secret that the components come from Infragistics and DevExpress. In the beginning we where upgrading when new versions came along, but as the time went by the upgrade frequency dropped. So now it’s little over a year since our last component upgrade and quite a few things have happened since then.

    At the time of writing I’m planning how we are going to migrate from .Net Framework 1.1 to 2.0 and that’s when these problems came to light. I’m not very keen on running our software in 2.0 and having our 3rd party components targeted for 1.1 running in 2.0. So the best thing to do is to upgrade the components as well. The only problem is that their API’s have changed and the migration toolkits they offer don’t really work that well. So know I’m sitting here trying to calculate the complexity of this migration (which was complex enough already), trying to figure out where we need to make changes in our code, how long it will take us, how much it will cost us to renew licenses, how happy our developer get when they hear about this plan and that I haven’t bought a single christmas gift yet! Right now it makes my head spin, so if anyone have any good recommendations on how to solve this little issue, please let me know!
    Thursday, December 14, 2006 1:00:00 AM (W. Europe Standard Time, UTC+01:00)
    Monday, November 27, 2006
    At work today I was doing some searching in a C# file to find strings that we haven’t translated. E.g. messages to the user and so forth. I thought using RegExp to do this would be a good idea. That made me think of a joke I heard from Scott Hanselman at TechEd this year:
    “You have a problem and find out you have to solve it with RegExp. Now you have two problems…”.
    Anyway, I did a search and found the syntax I was looking for at http://msdn2.microsoft.com/en-us/library/2k3te2cs%28VS.80%29.aspx. To solve my problem I used :q, which gave me hits like “some string”. I guess I could have gone even further and made it even more specific for my search, but this was sufficient for me. I’ve used quite a bit of RegExp before and it’s really powerful, once you get used to it. And that is probably the biggest problem with RegExp, it’s hard! When you finally have memorized some syntax, a week later it’s gone. And also that it vary a lot from implementation to implementation. Like RegExp in Find is not the same as RegExp in C#.
    Monday, November 27, 2006 1:00:00 AM (W. Europe Standard Time, UTC+01:00)
    Tuesday, October 31, 2006

    In my last post about memory leaks, I emphasized the importance of calling Dispose. This time I’m going to talk about how you can see how much memory your application is using.

    You probably think that I think you’re stupid… Right? Right now you say to your self

    Of course I know where to find my app’s memory usage! I’m not f$£@&g stupid!

    Ok. I get it. You of course go to the task manager and look at the memory usage column for you app. Right? Wrong. Don’t do that. It dos not tell you anything about your app’s memory usage. Why? First here’s an example to make a point (or rub it in…):


    .Net application just started.

    Here I have started my test application and as you see it has a memory usage of 11 696K.

    The funny thing is that if you minimize the application it only has a memory usage of 812 K.


    .Net application minimized.

    What happened? Did all my objects just disappear when I minimized my app. I don’t think so! The problem is that Mem Usage equals working set (http://support.microsoft.com/kb/293215). And what dos working set tell you? One of the more common definitions of working set is;

    The working set of a process is defined as the number of virtual memory pages that it is allowed to keep resident in RAM.

    In other words; it dos not tell you how much memory your app are using.

    Now we know that Mem Usage is not much use to us, what CAN we use? What you want is your applications private memory. Private memory is the actual space in memory your application use. And as it happens, you can find that column in Task Manager as well… Only it’s called Virtual Memory. Go figure. In Task Manager go to View -> Select Columns…, and select Virtual Memory.

    So my advice to you is to get rid of the Mem Usage column and replace it with Virtual Memory. Do this on all the computers at your office and tell everyone!

    Tuesday, October 31, 2006 1:00:00 AM (W. Europe Standard Time, UTC+01:00)
    Sunday, October 22, 2006
    Scott Guthrie (General Manager at Microsoft Developer Division) writes in his blog that ASP.Net AJAX Beta 1 was released on Friday! If you want to download go here, for more information go to http://ajax.asp.net/ or se Scott’s blog at http://weblogs.asp.net/scottgu/.

    I have not done any real development in any language supporting the AJAX phenomenon yet, so I’m really excited to get started and see what all the fuzz is about.
    .Net | Ajax | Web
    Sunday, October 22, 2006 1:00:00 AM (W. Europe Daylight Time, UTC+02:00)
    Thursday, September 28, 2006
    "Hi! There are no memory leaks in .Net! It has that great garbage collector everyone's talking about! And the dispose pattern and all that".

    Not very likely that a person actually uttered this, but it’s a great start for a discussion. I’ll start mentioning some normal miss conceptions about GC, Dispose and that "stuff":
    • The garbage collector cleans up everything you keep laying around and you don’t need to worry about it.
    • If you just do your cleanup in Dispose the GC will call dispose for you.
    • If you really want to be sure, do your cleanup in the destructor and your home free.
    Nice! Lets just do this and we can all go home… Or you can read on…:
    • The garbage collector cleans up everything you don’t use anymore. That is all objects not referenced by your running program.
    • If you do your cleanup in Dispose, YOU have to remember to call it! Not only that, if you use objects that have Dispose methods, you need to call them as well!
    • You can do cleanup in the destructor, but it’s much more efficient to use the Dispose pattern. More on this later.
    I think most of us know that the garbage collector only releases objects with no running references to it. What’s interesting though is that not everyone knows that you have to call Dispose on all objects that have a Dispose method! I can not emphasize this enough (even though I tried with bold text).

    You have a gene in your body as developer to call Close methods (on file handles, data connection etc), but no one ever mentioned Dispose for you. Or you where told that the GC call Dispose for you, or something else that sounded good at the moment.
    Thursday, September 28, 2006 1:00:00 AM (W. Europe Daylight Time, UTC+02:00)
    RSS RSS - Comments Twitter LinkedIn
             
    SEARCH
     
     
             
    TOP POSTS
       
             
    NAVIGATION
       
             
    CATEGORIES
      .Net (61) ADFS (3) Agile (30) Ajax (5) Architecture (20) Articles (1) ASP.NET (6) ASP.NET-MVC (1) Blogging (12) Books (2) BPEL (1) CleanCode (1) CloudComputing (7) Community (4) CSharp (11) DasBlog (5) Database (2) DDD (5) Deployment (16) DSL (1) Events (38) ExtremeProgramming (6) Fun (6) Gadgets (4) IIS (10) InfoQ (4) Java (2) Lean (3) Linq (2) MemoryLeaks (5) Microsoft (37) MVC (1) NDC (2) NNUG (36) Other (10) Patterns (9) Performance (3) Scrum (17) Security (7) ServiceBus (1) Silverlight (4) Software (19) TeamManagement (11) TechEd (7) Testing (4) Tools (25) TvGuide (1) WCF (8) Web (15) WebDeploy (1) WIF (3) Windows (10) Vista (15) VisualStudio (16) WiX (9) Work (16) Workflow (3)  
             
    ARCHIVE
       
             
    BLOGROLL
       
             
    ON THIS PAGE...
     
    No-Click Web Deployment – Part 2 – Web Deploy (a.k.a. msdeploy)
    NNUG Presentation – Udi Dahan on NServiceBus
    Home Realm Discovery In WIF And ADFS 2.0 By Query String
    Some useful WIF resources
    Presenting Windows Identity Foundation At MSDN Live In April
    QCon London Early Bird About To Expire
    Live Meeting With Phil Haack On MVC 2 – August 26th
    Are SharePoint Developers Unable To Be Real Craftsmen?
    Replace Comments With Code
    Start Using More Value Objects!
    Different Ways of Refactoring Switch/Case
    Refactoring TryParse Into a Value Object
    Mark Nijhof on FubuMVC at the next VAN meeting
    InfoQ: Interview With Chad Myers on FubuMVC
    Article: Microsoft Azure - A new era for software companies?
    Next Europe VAN meeting announced
    Don’t forget Monday’s Virtual ALT.NET meeting
    Greg Young on DDD
    The Future of Microsoft .NET Programming Languages
    Amazon Web Services compared to the Azure Services Platform
    Azure Services Platform and .Net Services presentations
    Microsoft Azure Services Platform
    Naked Objects - DDD framework for .Net
    WiX and DTF: Using a Custom Action to list available web sites on IIS
    Which version of WiX is going to be distributed with VS 2010
    WiX and DTF: Using a bootstrapper to force elevated privileges in Vista
    WiX and DTF: Introduction
    Fluent email interface
    Bug in Hotmail (update)
    Bug in Hotmail forces me to apologize
    New features in TFS2008 SP1
    Pex: Automated Exploratory Testing for .Net
    Are you deploying applications to Windows Vista, and doing ok?
    The history behind .Net User Groups
    ClickOnce - Server Deployment
    Are you developing software with a keyboard or mouse?
    Norwegian .Net User Group in Bergen and JavaBin Bergen join forces
    Our MSI installation got too big for Win Server 2003!
    Norwegian Developer Conference in Oslo
    Fantastic NNUG meeting!
    Developer conference in Bergen?
    Visual Studio 2008 and .Net Framework 3.5 to be released late November
    TV Program Guide - LINQ
    Last episode of The .Net Show!
    Hosting WCF services in WAS
    Having problems after Security Update for .Net 2.0 (KB928365)?
    Want to know what type System.__ComObject really is?
    Going to a .Net devcon in 2007?
    Visual Studio (Orcas) Beta 1
    New features in C# Orcas
    New page at P&P
    It's official
    Memory leaks - objects anchored to events
    Bypassing DTO proxies on WCF
    Asp.net AJAX RC and Visual Studio 2005 SP1
    Web2.0 confusion
    The 3rd party components problem
    Using RegExp in Visual Studio’s Find
    Memory Leaks in .Net Part #2
    ASP.Net AJAX Beta 1 (codename ATLAS) was released on Friday!
    Memory leaks in .Net Part #1