Through WS-Addressing services can require a certain value in the ws-addressing <wsa:to> SOAP header. WCF has full support for this. This support is inherited by the WCF-Adapters. When using WS-addressing in a BizTalk Server Send Port what you enter in the “Address (URI)” of the WCF adapters configuration will also be the value that ends up in the <to> header.

Like so:

image 

This will produce the following. Other headers and body removed for clarity.

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
  <s:Header>
    <a:To s:mustUnderstand="1">http://localhost:8990/Service1</a:To>
  </s:Header>
  <s:Body>
    ...
  </s:Body>
</s:Envelope>

If you need to have a different value in the <to> header than the actual address that the service is hosted at it becomes a little bit trickier. You need to use the WCF-Custom adapter and add the ClientVia behavior. The value configured as the “Address (URI)” will still end up as the value in the <to> header, but the actual URI that the call will be made to will be the value you configure in the ClientVia’s viaUri property.

Like so:

image image

This will produce the following (again cleaned for clarity):

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
  <s:Header>
    <a:To s:mustUnderstand="1">http://somedummyvalue/</a:To>
  </s:Header>
  <s:Body>
    ...
  </s:Body>
</s:Envelope>

Now, as long as the value that you want in the <to> header is http or https (depending on the bindings security settings) then you are fine. However, if you end up needing to have a value in your <to> header that looks for example like this: urn:company/path/subpath/Service1, then you’re in trouble.

You will get an error dialog saying that The specified address is invalid. Invalid address scheme; expecting “http” scheme.

image

Why? Because BizTalk Server in its diligence to help you configure things correctly will force you to enter an URI that is prefixed with either http or https (again, depending on the security setting of the binding). There is no way for you to configure a non-http prefixed port in the adapter GUI (that I know of).

A colleague of mine, Gustav Granlund, experienced this issue and found a solution: you can coup it in through a binding file, and the runtime will accept it. Doing this you can enter a “Address (URI)” like so:

image

And you are then able to send a message that looks like this (to an address of http://localhost:8990/Service1):

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
  <s:Header>
    <a:To s:mustUnderstand="1">urn:company/path/subpath/Service1</a:To>
  </s:Header>
  <s:Body>
    ...
  </s:Body>
</s:Envelope>

The caveat is that after having done this you cannot open and change WCF adapter settings in the port through the administration console GUI and keep the urn:company/path/subpath/service1 style URI. But, as mentioned, BizTalk will happily run with it. In a follow up post I examine another option.

HTH,
/Johan


Blog Post by: Johan Hedberg