Introduction
One of the good features of BizTalk server is the extensibility of WCF adapter. WCF (Windows Communication Foundation) enables developers to extend and updates its standard run time behavior with several extensibility points like behavior, binding, binding element, channels, etc.In this post, I will explain the followings:
- How to extend BizTalk WCF Adapter?
- Illustrate how to overcome one of the limitations of WCF Adatpter
Problem
I faced an issue when I tried to integrate with a web service of one of our customers.
They sent us a web service url and this url is a long url (261 characters!!) when I tried to configure a BizTalk WCF adapter it gave me the following error as shown in figure 1:
"Error saving properties.(System.ArgumentException) Invalid address length; specified address length is 261 characters, limit is 256 characters."
Figure 1. Error Message
If you try to consume a web service using a console application you will not face any issue related to url length because there is not a limit for address property.However, BizTalk WCF adapter has a limit because BizTalk team defined End Point Address property of WCF Adapter as type of URI with length 256.
Solution
To work around this issue, WCF adapter provides the capabilities to be updated and extended.
What we need is to have custom endpoint behavior and to provide a dummy url to EndPoint Address URL and provide a real long address in an extended custom property
To prepare a custom endpoint behavior we need to followings the following steps:
- Create a class library project and we will call it as TechnetWiki.CustomEndpointBehavior as shown in
figure 2
Figure 2. Creating Class Library Project - Now we need to create 2 classes one to extend abstract class BehaviorExtensionElement to define custom property for our custom url and interface IEndpointBehavior to set a custom url to Endpoint url at run time.To use these abstract class and interface we need to add reference to System.ServiceModel dll as shown
- Create a new class and we will call it as CustomBehaviorExtensionElement
that extends BehaviorExtensionElement
using
System;
using
System.Configuration;
using
System.ServiceModel.Configuration;
namespace
TechnetWiki.CustomEndpointBehavior
{
public
class
CustomBehaviorExtensionElement : BehaviorExtensionElement
{
private
ConfigurationPropertyCollection properties;
[ConfigurationProperty(
"CustomAddress"
)]
public
Uri CustomAddress
{
get
{
return
(Uri)
base
[
"CustomAddress"
];
}
set
{
base
[
"CustomAddress"
] = value;
}
}
public
override
Type BehaviorType
{
get
{
return
typeof
(CustomEndpointBehavior);
}
}
protected
override
ConfigurationPropertyCollection Properties
{
get
{
if
(
this
.properties ==
null
)
{
this
.properties =
new
ConfigurationPropertyCollection
{
new
ConfigurationProperty(
"CustomAddress"
,
typeof
(Uri),
null
,
null
,
null
, ConfigurationPropertyOptions.IsRequired)
};
}
return
this
.properties;
}
}
protected
override
object
CreateBehavior()
{
return
new
CustomEndpointBehavior(
this
.CustomAddress);
}
}
}
- Create another class called CustomEndpointBehavior that extends IEndpointBehavior
interface
using
System;
using
System.ServiceModel.Description;
namespace
TechnetWiki.CustomEndpointBehavior
{
public
class
CustomEndpointBehavior : IEndpointBehavior
{
public
Uri CustomAddressUri {
get
;
set
; }
public
CustomEndpointBehavior(Uri customAddressUri)
{
if
(customAddressUri ==
null
)
{
throw
new
ArgumentNullException(
"customAddressUri"
);
}
this
.CustomAddressUri = customAddressUri;
}
public
void
AddBindingParameters(ServiceEndpoint serviceEndpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
}
public
void
ApplyClientBehavior(ServiceEndpoint serviceEndpoint, System.ServiceModel.Dispatcher.ClientRuntime behavior)
{
serviceEndpoint.Address =
new
System.ServiceModel.EndpointAddress(
this
.CustomAddressUri);
}
public
void
ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
{
}
public
void
Validate(ServiceEndpoint serviceEndpoint)
{
}
}
}
- Sign assembly by defining a strong key for the class library project as shown in
figure 3
Figure 3. Sign the assembly. - Add assembly to GAC either by adding assembly to resources of BizTalk Application in BizTalk administration as shown in
figure 4 or by run gacutil -i "{AssemblyPath}" command.<
Figure 4. Adding Assembly to GAC - To register behavior extensions to WCF Adapter, you need to update machine.config in path "C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\machine.config" by adding the following configuration inside behaviorExtensions
tag <add name="customEndpointBehavior" type="TechnetWiki.CustomEndpointBehavior.CustomBehaviorExtensionElement, TechnetWiki.CustomEndpointBehavior, Version=1.0.0.0, Culture=neutral, PublicKeyToken=415d904e2f9a9bcd" />
Note: in case your WCF-Custom handler runs under 64 bit you need to update the machine.config in the following path "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config" - Now we are ready to use extension in WCF adapter, you need to create WCF-Custom send adapter and set any dummy url in Address (URI) as shown in figure 5
- Select Behavior tab and right click EndPointBehavior then select customEndPointBehavior which is the extension the we created and define in machine.config as shown in
figure 6
Figure 6. Select Extention - Set the real URL which has the long url as shown in figure 7
Figure 7. Custom URL Setting
Conclusion
BizTalk Server enables developers to extend WCF adapter to overcome any limitations in WCF capabilities. In this post we explained one of the scenarios that needed to extend WCF to overcome the limitation of WCF Adapter and we walk-throw in the steps needed to register wcf extension in WCF-Custom Adapter.See Also
Another important place to find an extensive amount of BizTalk related articles is the TechNet Wiki itself. The best entry point is BizTalk
Server Resources on the TechNet Wiki.