More Thoughts on HTML5, CSS3 & WebKit Advances!

Yesterday I wrote a post on Why Safari May Become the Browser of Choice and got some great feedback (both positive and negative) in the comments and several emails. I thought I'd take this opportunity to address this feedback and explain a little bit more about why I believe these new "features" in WebKit are so important to the future of web development and design.

First off, let me set the record straight and tell you that I am an unqualified supporter of Microsoft technologies such as SQL Server, BizTalk Server, Commerce Server and the .NET Framework. I'm also a Microsoft MVP for Commerce Server and an avid C#, ASP.NET and BizTalk developer. In my day job, I use these Microsoft technologies to create business-to-business e-commerce applications for the company that I work for.

But at night and on the weekends, I moonlight as a free-lance web designer/developer using mostly non-Microsoft technologies such as Ajax, PHP & mySQL. In both areas I strive to create "standards" based web sites and applications and my overriding goal is always to "create the best user experience requiring the least bandwidth" and this is where WebKit comes in.

Think about how we (ASP.NET) developers create great user experiences today and two things come to mind; ASP.NET AJAX and Silverlight. Both technologies allow you to create really great user experiences on the web but only at the cost of bandwidth (download time, initial or otherwise). The same rule holds true for Flash and any Ajax library such as Prototype, script.aculo.us or jQuery (all of which are excellent Javascript frameworks).

Now think about our potential to create great user experiences using nothing more than the new HTML5 and CSS3 capabilities found in the latest WebKit builds. Gradients, shadows and rounded-corners without images, transforms and animation without Javascript, client-side data that goes way beyond cookies and support for highly compressible vector graphics (SVG). All in a fully "standards" based HTML/XHTML/CSS framework that (hopefully) renders the same in all browsers, both desktop and mobile.

Now we're talking about actually having the tools to "create the best possible user experience requiring the least bandwidth". This may be a pipe dream but it looks like the WebKit folks and I are drinking the same Kool-Aid at the moment!

 

Currently listening to: "Still Feels Good" by Rascal Flatts

Configuration Wizard – Failed to Connect

Configuration Wizard – Failed to Connect

When specifying the SQL server, Configuration Database name and account for SharePoint you may see the following error

Failed to connect to the database server or the database name does not exist. Ensure the database server is a SQL server, and that you have appropriate permissions to access the database server. To Diagnose the problem, review the extended error information located at c:\program files\common files\microsoft shared\web server extensions\12\logs\PSCDiagnostics <DATETIME>.log. Please consulte the SharePoint Products and Technologies Configuration Wizards for help or additional information regarding the databse server security configuration and network access.

When you look at the log you will probably see some kind of timeout exception at the bottom, right before it all exploded.

LOTS of things could be causing this.  Below is a list of item that I have seen in my travels.

SQL Server Problems

  1. It was OFF,
  2. the service was stopped,
  3. the remote TCP/IP connections were not configured for SQL 2005
  4. SQL was sysprepped and the name was changed and it was just generally messed up and had to be rebuilt (Life Lesson: Just install SQL normally, perhaps record an unattended, but don’t bring an image of a Sysprepped SQL and try to rename the computer [regardless if it has domain membership] )

Network/Security Problems

  1. Router was melted,
  2. firewall was blocking access,
  3. logged in account really did not have the right permissions on the SQL server (see technet for details of required access),
  4. Cluster name was wrong (DUH),
  5. Cluster was offline
  6. Account was local (not domain)
  7. Recent DNS/IP change, needed to flushdns on SharePoint server
  8. Admin password was changed while logged on, needed AD refresh between DCs

This is not likely a bad username/password problem. You will see a different message for that.

Technet Snippit

NoteImportant

The server farm account is used to access your configuration database. It also acts as the application pool identity for the SharePoint Central Administration application pool, and it is the account under which the Windows SharePoint Services Timer service runs. The SharePoint Products and Technologies Configuration Wizard adds this account to the SQL Server Logins, the SQL Server Database Creator server role, and the SQL Server Security Administrators server role. The user account that you specify as the service account must be a domain user account, but it does not need to be a member of any specific security group on your Web servers or your back-end database servers. We recommend that you follow the principle of least privilege, and specify a user account that is not a member of the Administrators group on your Web servers or your back-end servers.

Try this to help diagnose

  1. Ping SQL/Cluster name
  2. Browse to \\ClusterName\C$ (this will tell you if your logged in account has admin permissions on that box)
  3. If SQL is a cluster, be sure which node is active
  4. Open the SQL server in SQL Management Studio
  5. Check for AV or firewall software on SQL server blocking the access
  6. Try user name as domain\username (NOT username@domain)
  7. Check the lists of all the stuff that can go wrong (above) and be sure you are not having those problems.
  8. If all else fails, just call PSS or your Microsoft Technical Account Manager (if you have one)

WCF: Contract name could be any on the client side

WCF: Contract name could be any on the client side.Sometimes we’ve got a very clear fault message:          <faultstring xml:lang=”en-US”>Could not find default endpoint element that references contract ‘ServiceProvider_configuration_Ref.ConfigurationServicePortType’ in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.</faultstring>
         <detail>
            <ExceptionDetail xmlns=”http://schemas.datacontract.org/2004/07/System.ServiceModel” xmlns:i=”http://www.w3.org/2001/XMLSchema-instance”>
               <HelpLink i:nil=”true”/>
               <InnerException i:nil=”true”/>
               <Message>Could not find default endpoint element that references contract ‘ServiceProvider_configuration_Ref.ConfigurationServicePortType’ in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.</Message>
.
It means two things do not conform each other:1)      The contract attribute in the endpoint element of the config file:   <endpoint address=“https://ie-services-configuration.ServiceProvider.com“binding=“customBinding“ bindingConfiguration=“customBinding_Configuration“    contract=“MyCompany.MyProject.ServiceProvider_configuration_Ref.ConfigurationServicePortType“      name=“ConfigurationServiceHttpPort“ /> 2)       And ConfigurationName property of the ServiceContract attribute in the proxy code. It usually generated by Add Service Reference wizard and placed in the hidden file the Reference.cs

     [System.CodeDom.Compiler.GeneratedCodeAttribute(“System.ServiceModel”, “3.0.0.0”)]    [System.ServiceModel.ServiceContractAttribute(
Namespace=“http://ws.ServiceProvider.com”, ConfigurationName=“ServiceProvider_configuration_Ref.ConfigurationServicePortType”)]
    public interface ConfigurationServicePortType {
 How I could get this situation? Very easily. For instance when I am editing my .config file with the Microsoft Service Configuration Editor and selecting to fix my endpoint -> contract name. I choose the dll with the definition of the service contract and there we go! It shows me not the ServiceProvider_configuration_Ref.ConfigurationServicePortType but MyCompany. MyProject.ServiceProvider_configuration_Ref.ConfigurationServicePortType and this creates the error mentioned above. We fix this error easily by changing the config file. Of course we can change the Reference.sc but it is generated be wizard and after updating this reference the error appears again. Is it a whole story? Nope. It is more interesting. Say we have the source code for this Web-service. Then we are creating the client for this Web-service. We are waiting that the full name of the service class should be the same in the service source code and in the client proxy code. It’s wrong! It is completely wrong.That means the “loose coupling” J What the client could get from the service it is the metadata: one or many wsdl-s and schemas (xsd).  Inside there is only the contract name. Usually it is the name of service interface or, if you apply the [ServiceContract] right to the service class, the service class name. The namespace of it does not passed by the metadata! When one of the client tools generates the proxy code it usually adds some new namespace. For example the Visual Studio adds the Default namespace parameter from the project properties.What about the service class name? The metadata passes the name under the [ServiceContract] attribute. And the client tool that generates the proxy code does not know is it the name of the interface or the name of the class. Then is just creates the interface with this name and with the [ServiceContract] attribute. Then it creates the class derived from this interface. And this class has auto generated name!What about the service contract full name?For instance:the source code of the web-service:namespace CMS_Stub { [ServiceContract(
Namespace = ” http://ws.ServiceProvider.com “)]
public interface ICMS_Stubpublic class CMS_StubService : ICMS_Stub the client proxy code:namespace MyCompany. MyProject.ServiceProvider_configuration_Ref {[ServiceContract(
Namespace = ” http://ws.ServiceProvider.com “,
ConfigurationName=“ServiceProvider_configuration_Ref.ICMS_Stub”)]
public interface ICMS_Stubpublic class CMS_StubClient: ICMS_Stub And what we see in the contract attribute in the endpoint element of the client config file?


  • CMS_Stub.ICMS_Stub?

  • CMS_Stub.CMS_StubService?

  • MyCompany.MySolution.MyProject.DownloadUri.ServiceProvider_configuration_Ref.ICMS_Stub?

  • MyCompany.MySolution.MyProject.DownloadUri.ServiceProvider_configuration_Ref.CMS_StubClient?

  • ServiceProvider_configuration_Ref.ICMS_Stub?
Yes, you are right, the last one, the ConfigurationName of the ServiceContract.   

BizTalk RFID knocked my socks off…yet again!!!

BizTalk RFID knocked my socks off…yet again!!!

I’ve got a RFID project in the pipeline and I’m doing a ‘little playing’ at this point
– seeing how far I can go through the APIs given this certain Reader and BizTalk
RFID Client APIs
. (I’m home and hosed on the BizTalk RFID APIs, but the questions
are more around the particular Provider AND what the device can/can’t do)

So I decided to venture a little further………..

Fired up a VPC and seeing this Reader is a USB connected device, (and as we know that
VPC/Virtual Server/Hyper-V 2008 does not share USB ports!!! After a little pain I
found a 3rd party software piece that did the job!) had to share it from another physical
host where the Reader is plugged into.

After a little playing with Provider/Device Settings within BizTalk RFID Manager –
away we go.

I decided to cut some code and do a GetDeviceCapabilities(…) sort
of call.

Check this out!!!!!

Line 25 – was my call on the Open Connection.

** I decided to run the code in debug mode and entered the same command in the Intermediate
Window

This was the part that took the cake….it’s got a whole collection of ENGLISH
TEXT as to what the device does!

If you’re like me…so many of these things fall down to byte structures with certain
bits here and there indicating different capabilities.

HOW GOOD IS THIS!!!! Well done to the RFID Team…..it’s great to have APIs that make
sense…. 🙂 (mostly smile_eyeroll)

VHD Heaven – MS has a little stash for download

I came across this Microsoft
Page
while on my travels which lets you browse for your VHD by product!!!!!

e.g. SQL 2008, BizTalk, SharePoint, VS2008 etc etc. Grab the VHD for your needs.

They are public domain VHDs so I’m guessing they’re ‘limited’ in some way (probably
time) – which means don’t go building your VOIP/RFID Corporation on them 🙂

Have fun!

Speaking at Developer Summit on Masterdata Management using BizTalk 2006

I recently spoke at the leading developer conference here in Sweden called Developer Summit. The talk was called Masterdata Management using BizTalk 2006. The slides can be found here.

I can really recommend Developer Summit as a conference. Everything is super well organized and having the opportunity to listen to celebrities like David Chappell, Jim Webber, Dan North and Christian Weyer in Sweden is really great!

This year I also liked the mix of presentation as some where more general presentation as for example Benjamin Ling who’s the director of platform at Facebook and who gave an insight to how the platform is managed and developed. I also really enjoyed (besides the obvious ones as for example Christian Weyer’s WCF talk) Frans Hanel’s talk on the history and architecture behind a major price comparison site called prisjakt.nu – very interesting and a great technical mix in otherwise Microsoft focused conference.

Speaking at Developer Summit on Masterdata Management using BizTalk 2006

I recently spoke at the leading developer conference here in Sweden called Developer Summit. The talk was called Masterdata Management using BizTalk 2006. The slides can be found here.
I can really recommend Developer Summit as a conference. Everything is super well organized and having the opportunity to listen to celebrities like David Chappell, Jim Webber, […]

BizTalk Server 2006R3

By now many of you will have heard the announcement for BizTalk Server 2006 R3. You can read about it on Steve Martin’s blog.

In addition to being a “synching” release that enables compatibility with SQL 2008 and VS.NET 2008, the high points (from the post) are:

  • New web service registry capabilities with support for UDDI (Universal Description Discovery and Integration) version 3.0
  • Enhanced service enablement of applications (through new and enhanced adapters for LOB applications, databases, and legacy/host systems)
  • Enhanced service enablement of “edge” devices through BizTalk RFID Mobile
  • Enhanced interoperability and connectivity support for B2B protocols (like SWIFT, EDI, etc)
  • SOA patterns and best practices guidance to assist our customer’s implementations

I think the most interesting part is the UDDI bit. This marks a migration of UDDI from the base OS (in Win2K3) into BizTalk Server. When I first saw that, I was surprised, but, thinking about it, it really makes a lot of sense. The migration of registry functionality is actually a steeping stone step, moving us closer to what Oslo will bring, where the process server is tightly tied to the registry (now) or repository (later, in Oslo).

This is also great news and a really good move for current BizTalk devs, as hopefully it will help move registry access more into the mainstream. And once you drink the registry koolaid, you’re well on your way to ESB nirvana 🙂

Technorati Tags: BizTalk,SOA,ESB Guidance,Oslo,ESB

Writing BizTalk context properties to a message from a WCF service using behaviors

Writing BizTalk context properties to a message from a WCF service using behaviors

The new WCF adapter in BizTalk 2006 R2 offers a lot of new possibilities. One of those is to write data to the BizTalk Message context properties directly from an exposed WCF Service. A practical use of this technic could be to write the username from the Windows credentials of the calling client into the context of the BizTalk message. This could be useful as this information is encrypted in messages that are received via the WCF adapter and isn’t possible to read when inside BizTalk. I’ll try and demonstrate the technique in this post.

If you have used the SOAP adapter before you might know that all you had to do was to turn on Windows based security for the exposed SOAP service and the username was automatically promoted to the context of the incoming BizTalk message. That username could then be used for routing, tracking which user called the service or using the value in plain text when communicating further to other connected systems. However using the WCF adapter this is not true anymore – when using the new WCF Message Security model the username and password is encrypted in the message and once the message is received by BizTalk it’s to late to read it. Basically we have to read the username in the actual service and write it into our own context property (that doesn’t get encrypted).

One way of achieving this is to read the username in the service and then to add it to the WCF Message Headers. All WCF message headers will by default be written to a the BizTalk Message context property called InboundHeaders (in the http://schemas.microsoft.com/BizTalk/2006/1/Adapters/WCF-properties namespace). First we’ll create an EndpointBehavior that will use a MessageInspector to add the username to the message header. Finally we create BehaviorExtensionElement so we can use a WCF Custom Binding in BizTalk and configure it to add our new behavior.

Creating the new EndpointBehavior

To create the configurable behavior we’ll need the three classes we mentioned above.

  1. A class that implements the IDispatchMessageInspector interface to handle to reading and writing to the actual message.

  2. A class that implements the IEndpointBehavior interface to define what kind of endpoint we’re creating and what it should do.

  3. A class that implements the BehaviorExtensionElement abstract class to create the behavior and make it configurable.

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Dispatcher;
    using System.ServiceModel.Description;
    using System.ServiceModel.Configuration;

    namespace CustomWCFProperties.Behavior
    {
    ///


    /// PromoteUserNameMessageInspector implements IDispatchMessageInspector and adds the name from the WindowsIdentity to a WCF header called WindowsUserName in the http://CustomWCFProperties.Schema namespace. BeforeSendReply only returns as we’re not interested in handling the response.
    ///
    public class PromoteUserNameMessageInspector : IDispatchMessageInspector
    {
    #region IDispatchMessageInspector Members

        </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">object</span><span style="color: #000000"> AfterReceiveRequest(</span><span style="color: #0000ff">ref</span><span style="color: #000000"> System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
        {
            </span><span style="color: #0000ff">string</span><span style="color: #000000"> windowsUserName </span><span style="color: #000000">=</span><span style="color: #000000"> ServiceSecurityContext.Current.WindowsIdentity.Name;
            request.Headers.Add(MessageHeader.CreateHeader(</span><span style="color: #000000">"</span><span style="color: #000000">WindowsUserName</span><span style="color: #000000">"</span><span style="color: #000000">, </span><span style="color: #000000">"</span><span style="color: #000000">http://CustomWCFProperties.Schema</span><span style="color: #000000">"</span><span style="color: #000000">, windowsUserName));
            </span><span style="color: #0000ff">return</span><span style="color: #000000"> </span><span style="color: #0000ff">null</span><span style="color: #000000">;
        }
    
        </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">void</span><span style="color: #000000"> BeforeSendReply(</span><span style="color: #0000ff">ref</span><span style="color: #000000"> Message reply, </span><span style="color: #0000ff">object</span><span style="color: #000000"> correlationState)
        {
            </span><span style="color: #0000ff">return</span><span style="color: #000000">;
        }
    
        </span><span style="color: #0000ff">#endregion</span><span style="color: #000000">
    }
    
    </span><span style="color: #808080">///</span><span style="color: #008000"> </span><span style="color: #808080"><summary></span><span style="color: #008000">
    </span><span style="color: #808080">///</span><span style="color: #008000"> PromoteUserNameBehavior implements IEndpointBehavior and adds a message inspector to the dispatch behavior. Doesn't use any binding parameters, doesn't validate any configuration etc and can't be used in a client (only in a service).
    </span><span style="color: #808080">///</span><span style="color: #008000"> </span><span style="color: #808080"></summary></span><span style="color: #808080">
    

    public class PromoteUserNameBehavior : IEndpointBehavior
    {
    #region IEndpointBehavior Members

        </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">void</span><span style="color: #000000"> AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
            </span><span style="color: #0000ff">return</span><span style="color: #000000">;
        }
    
        </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">void</span><span style="color: #000000"> ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
        {
            </span><span style="color: #0000ff">throw</span><span style="color: #000000"> </span><span style="color: #0000ff">new</span><span style="color: #000000"> Exception(</span><span style="color: #000000">"</span><span style="color: #000000">The method or operation is not implemented.</span><span style="color: #000000">"</span><span style="color: #000000">);
        }
    
        </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">void</span><span style="color: #000000"> ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
        {
            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(</span><span style="color: #0000ff">new</span><span style="color: #000000"> PromoteUserNameMessageInspector());
        }
    
        </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">void</span><span style="color: #000000"> Validate(ServiceEndpoint endpoint)
        {
            </span><span style="color: #0000ff">return</span><span style="color: #000000">;
        }
    
        </span><span style="color: #0000ff">#endregion</span><span style="color: #000000">
    }
    
    </span><span style="color: #808080">///</span><span style="color: #008000"> </span><span style="color: #808080"><summary></span><span style="color: #008000">
    </span><span style="color: #808080">///</span><span style="color: #008000"> Defines the behavior.
    </span><span style="color: #808080">///</span><span style="color: #008000"> </span><span style="color: #808080"></summary></span><span style="color: #808080">
    

    public class PromoteUserNameBehaviorElement : BehaviorExtensionElement
    {
    protected override object CreateBehavior()
    {
    return new PromoteUserNameBehavior();
    }

        </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">override</span><span style="color: #000000"> Type BehaviorType
        {
            </span><span style="color: #0000ff">get</span><span style="color: #000000"> { </span><span style="color: #0000ff">return</span><span style="color: #000000"> </span><span style="color: #0000ff">typeof</span><span style="color: #000000">(PromoteUserNameBehavior); }
        }
    }
    

    }

Finally we have to sign the assembly using a strong key and add it to the GAC.

Configure the machine.config

As we need BizTalk and the WCF adapter to pick up the need behavior and make it possible to configure our receive port we need to to add the behavior element to the machine.config.aspx). The easiest way of doing this is to use the new WCF Service Configuration Editor tool and point to the machine.config file.

After the dll been added and the machine.config file has been saved the the line below should have been added to the element (that is if you use the same strong name key as in the sample project I’ve linked here).

<div><span style="color: #0000ff"><</span><span style="color: #800000">add </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="addCustomWCFProperties"</span><span style="color: #ff0000"> type</span><span style="color: #0000ff">="CustomWCFProperties.Behavior.PromoteUserNameBehaviorElement, AddCustomWCFPropertiesBehavior, Version=1.0.0.0, Culture=neutral, PublicKeyToken=705e34637fdffc54"</span><span style="color: #ff0000"> </span><span style="color: #0000ff">/></span></div>

Create the BizTalk Receive Port and Receive Location

Next thing to do is to start the BizTalk WCF Service Publishing Wizard. Choose to publish a service endpoint and make sure you enable metadata and create a receive location. In this example we’ll next choose to “Publish schemas as WCF service” and then define our service by naming service operations and so on.

When you then browse to the URL you choose to publish your service to you’ll see the nice example of how to instance the service you just defined.

If we then send a request message to service (you’ll find a client as part of the attached solution here) and inspect the message and its context properties in BizTalk we’ll see that the username of the calling client is nowhere to be found.

Configure a WCF-Custom binding and adding a Endpoint Behavior

To add the username to the message context we’ll need to add our newly created behavior to our service. We’ll do this by switch the service over to use a WCF-Custom binding to enable configuration. We then need to add the URL in the address field, define the binding type to a wsHttpBinding and to add our addCustomeWCFProperties behavior to the list of endpoint behaviors.

>
> [![note](../assets/2008/04/windowslivewriterwritingbiztalkcontextpropertiestoamessag-72f4note-thumb.gif)](../assets/2008/04/windowslivewriterwritingbiztalkcontextpropertiestoamessag-72f4note-2.gif) NOTE: there is a limitation in the BizTalk WCF implementation in that you can’t create the WCF-Custom receive location that uses a HTTP in-process based binding (like the wsHttpBinding used in a WCF-Custom endpoint is) first and then use the WCF Publishing Wizard to only publish a metadata endpoint.
>
>

>
> [Richard Seroter writes about it here](http://www.topxml.com/code/cod-72_10213_biztalk-and-wcf-part-v-publishing-operations-patterns.aspx) and I found the same thing to be true.
>
>

>
> _”This error doesn’t have to do with mixing MEX endpoints and “regular” endpoints in the same IIS web site, but rather, creating MEX endpoints for in-process HTTP bindings seems to trigger this. **Note that an IIS-hosted MEX endpoint CAN be created for IIS-hosted HTTP endpoints, but not for in-process hosted HTTP endpoints.”**_
>
>

>
> If you however choose a different binding that Http or (as in this case) publishes the metadata first and then switches over to a custom binding you’re ok.
>
>

If we then post another message to the service and inspect the message we’ll see that the behavior actually added a header and that it’s part of our BizTalk context properties. The adapter is also smart enough to know that this header isn’t part of the original headers and therefore stores in it’s own field within the context properties (you’ll find as part of the InboundHeaders block as well).

One problem remains – the actual value of the user is nested inside a XML node and the property isn’t promoted.

Extract and promote the value

To extract and promote the value we use an old fashion pipeline component using the following code in the execute method (the complete project is part of the downloadable sample project).

<div><span style="color: #000000">        </span><span style="color: #0000ff">public</span><span style="color: #000000"> IBaseMessage Execute(IPipelineContext pc, IBaseMessage inmsg)
        {
            StringReader reader </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">new</span><span style="color: #000000"> StringReader(inmsg.Context.Read(</span><span style="color: #000000">"</span><span style="color: #000000">WindowsUserName</span><span style="color: #000000">"</span><span style="color: #000000">, </span><span style="color: #000000">"</span><span style="color: #000000">http://CustomWCFProperties.Schema</span><span style="color: #000000">"</span><span style="color: #000000">).ToString());

            </span><span style="color: #0000ff">if</span><span style="color: #000000"> (reader </span><span style="color: #000000">!=</span><span style="color: #000000"> </span><span style="color: #0000ff">null</span><span style="color: #000000">)
            {
                XPathDocument document </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">new</span><span style="color: #000000"> XPathDocument(reader);
                XPathNavigator navigator </span><span style="color: #000000">=</span><span style="color: #000000"> document.CreateNavigator();
                </span><span style="color: #0000ff">string</span><span style="color: #000000"> value </span><span style="color: #000000">=</span><span style="color: #000000"> navigator.SelectSingleNode(</span><span style="color: #000000">"</span><span style="color: #000000">/</span><span style="color: #000000">"</span><span style="color: #000000">).Value;
                inmsg.Context.Promote(</span><span style="color: #000000">"</span><span style="color: #000000">WindowsUserName</span><span style="color: #000000">"</span><span style="color: #000000">, </span><span style="color: #000000">"</span><span style="color: #000000">http://CustomWCFProperties.Schema</span><span style="color: #000000">"</span><span style="color: #000000">, value);
            }

            </span><span style="color: #0000ff">return</span><span style="color: #000000"> inmsg;
        }</span></div>

All the component does is reading the XML node the value exists inside and then it reads the actual value. Finally it writes the value back and promotes it. To be able to promote the value we also have to have a Property Schema deployed with a corresponding property name and namespace (WindowsUser and http://CustomeWCFProperties.Schema in this case).

The end results looks something like this.

The username is extracted and promoted and available for example for tracking or to for example use in a routing scenario.

This technique could of course be used for all kinds of scenarios where you like to add information to the context properties and could potentially replace a lot of the classic scenarios for custom pipelines.

All kind of comments are of course more than welcome!

Download the sample solution here.