BizTalk WCF Receive Location Configuration Error: The SSL settings for the service ‘None’ does not match those of the IIS ‘Ssl, SslRequireCert, Ssl128’
A BizTalk WCF endpoint is exposed with security enabled: SSL with a client certificate is required (so mutual, 2-way client and server authentication is configured).
BizTalk (2009) receive location is configured as follows:
(Incidently, the following command can be run in a Windows batch file to configure SSL for a IIS virtual directory:
%windir%\system32\inetsrv\appcmd.exe set config “Default Web Site/ServiceName” -commitPath:APPHOST -section:access -sslFlags:Ssl,Ssl128,SslRequireCert )
Error Message and Analysis
Clients were unable to connect to the service and the following exception message was written to the Application event log on the hosting BizTalk server:
Exception: System.ServiceModel.ServiceActivationException: The service ‘ServiceName.svc’ cannot be activated due to an exception during compilation. The exception message is: The SSL settings for the service ‘None’ does not match those of the IIS ‘Ssl, SslRequireCert, Ssl128’.. —> System.NotSupportedException: The SSL settings for the service ‘None’ does not match those of the IIS ‘Ssl, SslRequireCert, Ssl128’.
So this is an IIS configuration issue. The service is exposing some endpoint that is unsecured (the SSL setting for this endpoint is ‘None’, as mentioned in the error message), which doesn’t match the actual SSL settings configured: ‘Ssl, SslRequireCert, Ssl128’ (i.e. SSL with minimum 128-bit keys and client certificate required).
In this case, the endpoint not matching the SSL settings is the mex endpoint (i.e. the service WSDL).
Ensure that ALL mex endpoints are disabled, by commenting out the following mex binding configuration in the service Web.config file:
The <system.serviceModel> section specifies Windows Communication Foundation (WCF) configuration.
<serviceDebug httpHelpPageEnabled=”false” httpsHelpPageEnabled=”false” includeExceptionDetailInFaults=”false” />
<serviceMetadata httpGetEnabled=”false” httpsGetEnabled=”true” />
<!– Note: the service name must match the configuration name for the service implementation. –>
<!– Comment out mex endpoints if client auth enabled using certificates –>
<service name=”Microsoft.BizTalk.Adapter.Wcf.Runtime.BizTalkServiceInstance” behaviorConfiguration=”ServiceBehaviorConfiguration”>
<!–<endpoint name=”HttpMexEndpoint” address=”mex” binding=”mexHttpBinding” bindingConfiguration=”” contract=”IMetadataExchange” />–>
<!–<endpoint name=”HttpsMexEndpoint” address=”mex” binding=”mexHttpsBinding” bindingConfiguration=”” contract=”IMetadataExchange” />–>
I restarted IIS and the service could then be compiled and worked as expected.
Dynamic send ports allow adapter properties to be set at runtime (and also to select the adapter to be used). In my particular BizTalk 2009 scenario, I was creating a WCF dynamic send port to call a service endpoint URI only known at runtime, specified by the client (my orchestration is designed to be a generic message broker).
My first dislike was WCF configuration had to be defined programmatically in my orchestration. Sure, I was storing the properties in a custom SSO application so they weren’t hardcoded, but the BizTalk admin console provides a standard mechanism to configure WCF properties and it made sense to use it. Thinking of the BizTalk admins, I didn’t like the idea of hiding configuration away and then in a non standard way: it makes troubleshooting more difficult.
Secondly: performance. A few of my colleagues and sources on the web advised of poor performance using dynamic send ports for these reasons:
1. A dynamic send port is created each time it is used and in the case of WCF, for instance, the channel stack is created each time. This can have a significant performance hit. Further information about this is available here.
2. Only the default handler for each transport can be used which is a potential performance bottleneck if the host instance used by the default handler hasn’t been optimized for send operations. This limitation is also a recipe for inconsistent configuration (for example, if a design decision has been made to use a particular host for particular functions, this will not enforceable) and also it isn’t obvious to the BizTalk admins, what handler is used for a particular port. (Note that this limitation has been removed in BizTalk 2013 where it is now possible to choose a host instance for a dynamic send port, other than being stuck with just the default handler).
So I decided to use a static send port and override the “dummy” URI in my send port with the actual URI provided by the client… I did this as follows:
1. In my orchestration, in a Construct Message shape, I assigned to my own custom context properties, values that would later to be used to populate the BTS.OutboundTransportLocation and WCF.Action properties (these specify the endpoint URI and SOAP operation used by the WCF adapter, respectively). I did this instead of assigning directly to the “out of the box” properties since both were later overwritten on receipt of the message by the send port.
2. Using a custom pipeline component, I then promoted properties BTS.IsDynamicSend, BTS.OutboundTransportLocation and WCF.Action in a send pipeline assigned to the send port, populating BTS.OutboundTransportLocation and WCF.Action using the values assigned to my custom context properties like this:
inmsg.Context.Promote(“IsDynamicSend”, “http://schemas.microsoft.com/BizTalk/2003/system-properties”, true); // Set this to prevent URL caching.
inmsg.Context.Promote(“OutboundTransportLocation”, “http://schemas.microsoft.com/BizTalk/2003/system-properties”, endpointURL);
inmsg.Context.Promote(“Action”, “http://schemas.microsoft.com/BizTalk/2006/01/Adapters/WCF-properties”, operationName);
Note that BTS.IsDynamicSend has been set to “true”. As mentioned on MSDN here, this causes the send adapter to not used cached configuration, but to read configuration from the message context each time the send port is used. If BTS.IsDynamicSend was not set for example, then the cached endpoint URI would be used over the endpoint URI actually stamped on the message which was not what I wanted, since it’s possible that the endpoint may change between calls.
Performance: running my SOAPUI load tests, the response times of my web service were the same after changing to use a static port over a dynamic port. I’m using the WCF-Custom adapter with wsHttpBinding in my static send port. The response time of my web service was already acceptable to my client and my main motivation in using a static send port was better configuration options using the BizTalk admin console (rather than storing configuration in a custom SSO application). However better perfomance would have been nice! If I have time, I may investigate this further across the different adapters.
I got this error recently running the BizTalk WCF Consuming Wizard whilst working at a customers office when I didn’t previously (sensitive parts of the error message have been removed):
I think it was due to installation of internet security software on my development VM by the company’s infrastructure team and/or a new set of group policies being applied to the domain in which my VM is connected too…
Anyhow, it was obvious that all traffic from my VM was now going through a web proxy for the purposes of filtering traffic and I needed to install proxy client software. This would entail some internal processes being enacted.
Being impatient to progress (and seeing this as an opportunity to try something out that I had read about a few weeks previously) I decided to see if a I could use SvcUtil.exe, providing my proxy credentials so enabling the SvcUtil.exe to authenticate against the web proxy for me.
It would be great if the BizTalk WCF Service Consuming Wizard had proxy authentication support! Maybe I’m missing a trick here??
Based on this article here on Stack Overflow, I created a small proxy class, created a strong name key file for it and then installed it in the GAC on my dev VM:
I then edited my SvcUtil config file as follows, adding a reference to the proxy class assembly:
Then using the simple batch script below, I could run SvcUtil with proxy authentication included and hey presto, I could download the WSDL and associated XSD import files!
This saved me the annoyance of having to download each imported XSD file individually and then modifying the path in the parent WSDL.
I have a GitHub repo here containing the source code for the solution (as usual, provided under the terms of the MIT licence).
This is the last post in a four part series looking at BizTalk and WCF.
Here are the previous three posts:
In this final post, I will show how exception handling has been added to the RandomPresentService orchestration controlling our business process.
Some BizTalk Exception Considerations: 101 Course
Firstly, here is a quick brain dump of items that should be considered when thinking about handling exceptions in an orchestration:
- What are the customers requirements in regards to messages that fail inside BizTalk? Should alerting and/or logging be implemented so remedial action can be carried out and if so who should be the recipients of any such alerting? What steps should be carried out to recover from the error condition (what is the process)? Often the customer has only a vague idea here and some teasing out of requirements may be required.
- What is the impact if a particular process/action fails in your orchestration? Does this is invalidate subsequent previously successful actions? Should previously committed actions be rolled back therefore in a compensation block?
- What about business process type errors? Can these be handled without the need to jump to an exception condition? Preferably, business type errors that happen routinely (and are therefore not exceptional) should not be handled by throwing an exception but handled in the “body” of the orchestration.
- Do you need to handle any custom exceptions? Hopefully this is well documented in any service that needs to be consumed, for example.
Often error handling is forgotten until the very end of the development phase and is not instead considered at the start of a project – this is a mistake! Or alternatively, the customers requirements are not taken into consideration when building exception handling.
By thinking about exception handling at the start of a project, it can be “built in” to the solution. Also it allows time for discussions with the customer around how exceptions should be handled (in the analysis and design phase). It’s costly to implement exception handling logic retrospectively.
One of the big selling points in regards to BizTalk and another tenant of the platform is that it is “robust” and ensures “guaranteed message delivery”. In order to live up to these expectations it’s important that error conditions are handled in such a way that resubmission of failed messages is secured, with possibly multiple options for error recovery. These processes also need to be tested and well documented.
What Exceptions Need to Handled?
A concept that can be hard to determine is: what exceptions should my solution handle? By their very nature, exceptions are exceptional/rare so are a challenge to define and pin down.
It is a decision guided by some of the following factors:
- Experience – harnessed to try and make troubleshooting of “exceptional” type errors easier to investigate when the solution is running in Production.
- The needs of the customer.
- The type of exceptions that any called services could return.
This analysis will generate a list of exceptions that need to be handled.
As with any solution, the most specific exceptions should be handled first with the most general exception caught last.
And no doubt, not all exceptions will (or should) be catered for. They will generate a nasty runtime error that will require investigation using a tool like the Orchestration Debugger. This is where a good support team have a chance to shine :-).
Exception 1: PersistenceException
This is the first exception that I’m going to explicitly handle.
My friend and colleague Johann Cooper has written an excellent blog article about this exception.
Specifying direct binding on send ports in your orchestration is a good idea – this decouples physical send ports from the logical send ports specified in your orchestration. But this pattern can fail if the physical ports are ever unenlisted.
If physical ports are unenlisted, this removes any associated subscription and an exception of type Microsoft.XLANGs.BaseTypes.PersistenceException will manifest in the orchestration.
(You will also get a nonresumable “Routing Failure Report”, to help with troubleshooting the routing error).
So first up, I have modified the RandomPresentService orchestration like so:
- Added a non transactional scope shape around the send and receive shapes for the RandomPresentService WCF service.
- Added an exception block to the scope to handle the PersistenceException. This includes the creation of an ESB fault message (so the error will surface in the ESB exception management portal) and a suspend orchestration shape.
- Note the addition of looping: this ensures that the orchestration can be resumed in a valid state, since the RandomPresentService will be called again.
Exception 2: Handling SOAP Faults Returned from the RandomPresentService WCF Service
To handle any SOAP faults returned from the RandomPresentService service, I added a new fault type to the operation on the logical port in the orchestration designer (right click on the operation and select “New Fault Message”) and selected a message type of BTS.soap_envelope_1__2.Fault: this denotes that the fault should be wrapped in a SOAP version 1.2 fault:
The fault doesn’t need to be connected to a receive shape or anything like that – it can be left as is, and instead the fault can be handled by defining another exception block and selecting the SOAP fault as the “Exception Object Type”. When the fault is defined, it will subsequently be viewable in the “Exception Object Type” drop down, like so:
It’s important to handle SOAP faults: if not, this will cause an unhandled exception in your orchestration (due to an unexpected message type being returned) and it will not be possible to recover from this error by resuming the orchestration.
Also note that in order to extract the SOAP fault message, the orchestration XPath function can be used like this:
strFaultMsg = xpath(exSOAPFault, “string(/*[local-name()=’Fault’ and namespace-uri()=’http://schemas.xmlsoap.org/soap/envelope/’%5D/*%5Blocal-name()=’faultstring’ and namespace-uri()=”])”);
(Where strFaultMsg is of type System.String and exSOAPFault is of type Microsoft.Practices.ESB.ExceptionHandling.Schemas.Faults.FaultMessage).
Exception 3: Handling System.Exception – “Catch-all” Exception Blocks
The final exception block (that will be evaluated last by the orchestration engine) is a “catch all” block since it will handle exceptions of type System.Exception. Since all exceptions in .NET inherit from System.Exception, any errors, not previously handled explicitly by previous exception blocks, will be caught by this handler.
Also I have wrapped the entire orchestration in a global scope and specified one exception block for System.Exception to ensure than my default exception handling mechanism will be exercised.
So this concludes this four part series looking at BizTalk and WCF.
As is to be expected, WCF is interleaved tightly into the BizTalk framework and it is possible to leverage it heavily in your BizTalk solutions.
It’s been a journey looking at the creation of a WCF service; using the “out-of-the-box” BizTalk tooling to consume the service; building upon the artefacts created by the WCF Service Consuming Wizard; finally ending with this brief (!) look at implementing exception handling in the orchestration controlling the business process.
I hope it provides a good introduction to the subject!
(Both solutions are available under the terms of the MIT licence, a copy of which is included with each).
The first post looked at the RandomPresent WCF service and looked at design considerations, hosting and testing.
The second post touched on how to consume the WCF service from BizTalk, using the BizTalk WCF Service Consuming Wizard.
The business want to send to each customer, a random Christmas present with their order. To achieve this, the RandomPresent WCF service will be called by BizTalk and it will return a random present XML, wrapped in a SOAP envelope. The present response needs to be appended to the order, so the guys in the warehouse can add the present to the shipment.
It’s a matter of combining the original order and the response from the web service.
I’ll start with an overview of the single orchestration driving this process, since all other artefacts hang off this.
In the end, I created a new orchestration from scratch and didn’t use the one generated for me by the BizTalk WCF Service Consuming Wizard:
I will summarise the flow here and call out some interesting bits!:
- A map on my receive port converts the external format PO to the canonical version (check out my blog post here on the canonical messaging pattern). The canonical message has an element called “Status” that is assigned the value “NEW” in the map. This element is mapped to a property called “POStatus” of type MessageContextPropertyBase. So, as you can guess, I had to create a property schema which I added to my internal schemas project (it contains just this one property). The type MessageContextPropertyBase identifies “POStatus” as a context property that can be written to the context of a message and, as will be discussed, this is what I want to achieve for the purposes of routing and to prevent my orchestration from being caught in an endless activation loop.
- The canonical PO is written to the MessageBox and an instance of the orchestration fires up ; the orchestration subscribes to messages of type canonical PO and also on the “POStatus” promoted property: it is activated when the status is “NEW” only. The reason for this additional subscription on “Status” is because on completion, the orchestration will write the modified canonical PO to the MessageBox and an infinite activation loop will occur if orchestrations are activated only on publishing of a canonical PO message type (not good!). Of course, there are other ways of working around this: I think this is why, in some solutions I have seen, solutions have more than one canonical schema with a different namespace to differentiate them – this seems a mad way of getting around the “activation infinite loop” issue though, since this introduces the overhead of maintaining two canonical schemas and also the design principle of a canonical messaging pattern is that there is only “source of truth”.
- Note that I have designed my orchestration such that it only works with internal solution type messages only (not on the original, external, versions received). This protects the orchestration from changes to the format of the external PO which might require changes and redeployment of the orchestration.
- Next I create a request message for the RandomPresent WCF service… I have created a C# classes project that contains a C# class representation of the request schema: I created the class using Xsd.exe, by pointing Xsd.exe at my schema. I instantiate an instance of the request message in a Construct Message shape using the New keyword. Another way of creating a message in an orchestration is to create a map for this purpose. There is a serious caveat to instantiating a message using the New keyword however: it is vital that changes to the schema are reflected in the class representation (maybe this could be achieved in a Visual Studio “post build event” on the schemas project). As has happened to me in the past, if you assign a message created from your schema (via a map) to an (outdated) message created from a class (e.g. in a Construct Message shape), any missing elements will be silently lost in the output message… For some reason, creating a new message in an orchestration is a torturous process, it seems to me!
- A multipart message map combines the canonical and RandomPresent XML into a new instance of a canonical PO. This map will be discussed further in the “Maps” section below.
- Finally I set the “POStatus” context property to “PROCESSED” in a Message Assignment shape and write the new canonical message to the MessageBox. The final Send Shape initializes a correlation set but not for the purposes of supporting an asynchronous process, but for routing purposes: the correlation set contains just the “POStatus” context property and initializing this in the Send Shape causes the property to become promoted, enabling it to be used for routing. Setting this context property to different statuses on completion of processing is my way of preventing an endless activation loop, as discussed in point 1.
(Note the lack of error handling – this will be the subject of my next post).
The BizTalk WCF Service Consuming Wizard created the necessary schemas for me to communicate with the RandomPresent service however I deleted the RandomPresentService_schemas_microsoft_com_2003_10_Serialization.xsd schema (as discussed in part 2, I haven’t found a use for this schema yet). I also typically rename the service schema filename to something shorter and more descriptive.
If my solution modifies messages and/or involves an orchestration, I create 2 schema projects: an internal schemas project and an external schemas project, as is the case here.
Finally, a quick look at the map used to combine the canonical PO and the RandomPresent XML into a new instance of a canonical PO:
Typically, I use an inline XSLT template in my map for tasks such as these – I find it too frustrating and time consuming using functoids.
As mentioned in this previous blog post, I write my XSLT in a separate file and import it’s contents into my map.
This is the XSLT used:
So I hope you enjoyed this tour. In part 4 of this series, I will show how error handling has been implemented in the solution.
When the solution has been completed, I will make it available for download.
BizTalk and WCF, Consuming a WCF Service, Part 2 – The BizTalk WCF Service Consuming Wizard and a Look at the Artefacts Created
This post builds on part 1 of this series looking at BizTalk and WCF.
The previous post gave an overview of the RandomPresent WCF service, discussing design considerations, hosting and testing using SOAPUI.
In this post, we will examine how to consume the web service using the BizTalk WCF Service Consuming Wizard. The next post will delve into the detail of actually building our BizTalk solution, using (some) of the artefacts generated by the wizard.
Our mythical company is feeling generous and management have decided that each customer will receive a gift with their order. The gift will be assigned by calling our newly created web service and then adding an extra order line item for the present.
The BizTalk WCF Service Consuming Wizard
To consume the RandomPresent web service, the BizTalk WCF Service Consuming Wizard could be used. This will generate all the artefacts we need to invoke the service, into our BizTalk solution. However, some of the artefacts generated we will discard in favour of our own (better) implementation (to be discussed in part 3).
Here are the steps below:
- Right click on your solution (typically an external schemas project) and select Add –> Add Generated Items…
- Select Consume WCF Service in the Add Generated Items dialogue box. This will fire up the BizTalk WCF Service Consuming Wizard welcome page – click on the Next button
- On the next screen of the wizard we have two choices:
- Metadata Exchange (MEX) endpoint – this option enables a service description to be downloaded (WSDL file) by pointing the wizard directly to the running RandomPresent web service. Note from part 1 of this post, that we exposed a MEX endpoint by configuring the services web.config file to allow metadata to be downloaded via a HTTP GET
- Metadata Files (WSDL and XSD) – I always think of this as a second best option, since instead of downloading service data directly from source, this option will allow artefacts to consume the service to be created from a WSDL or XSD on the file system. There is a risk that the WSDL and/or XSD that has been obtained is out of date, so I try and avoid using this function if possible (it’s a last resort :-))
- Ensure that the Metadata Exchange (MEX) endpoint option is selected and click Next – this will take you to a screen where the service WSDL can be obtained and loaded into the wizard:
- (Note that it is common practice for a service endpoint to expose it’s service definition using the convention servicename?wsdl)
- Click Next and then Import. The wizard will then process the WSDL and generate artefacts into our BizTalk solution. Click Finish.
The Ajax.BT.Fulfilment BizTalk Solution
So the wizard has consumed our WSDL and generated various BizTalk solution artefacts into our BizTalk purchase order fulfilment solution. Lets take a quick look at what has been created:
- 2 x bindings files for importing into our BizTalk application: one of these files can be imported into our eventual BizTalk application to create a send port to communicate with the RandomPresent service:
- RandomPresentService.BindingInfo.xml – from the WSDL, the wizard has detected that the WCF service implements wsHttpBinding and therefore this file will create a send port using the WCF-WSHttp adapter
- RandomPresentService_Custom.BindingInfo.xml – this is another option for creating a send port in our BizTalk application. This will create a send port which will use the WCF-Custom adapter. Utilising this adapter offers greater WCF extensibility compared to the WCF-WSHttp adapter
- An interesting conundrum is: what bindings should I use in my solution, that utilising WCF-WSHttp or WCF-Custom? I would contend that WCF-Custom is the better option over WCF-WSHttp, to support future/evolving requirements
- RandomPresentService.odx – this is a “starter” orchestration to call the service and contains just the types required. I always move this orchestration into my specific orchestrations project (or just create an orchestration from scratch)
- RandomPresentService_schemas_ajax_randompresentservice.xsd – this schema defines the WCF message types required to construct a request to the service and what we can expect the response to look like
- RandomPresentService_schemas_microsoft_com_2003_10_Serialization.xsd – this contains type details. I suppose if you wish to serialize to a class representation, this XSD would be useful but otherwise I haven’t found a use for this
That’s it for now… In part 3 of this post I will walk you through my BizTalk solution utilising the service. This will build on artefacts created by the BizTalk WCF Service Consuming Wizard, which was the main topic of this post.
I thought I would do a series of posts on BizTalk and Windows Communication Foundation (WCF).
The main aim of this post is to cement my experiences so far exposing and consuming WCF services using BizTalk.
First up (and the focus of this post) is a look at a (very simple) WCF service that will be hosted in IIS. Further posts will detail how the service can be consumed using BizTalk and the tools available, error handling and recovery and monitoring.
What’s WCF you may ask? Further information/background is available here. In a nutshell, it is Microsoft’s implementation of remote communication specifications maintained by groups such as the World Wide Web Consortium (W3C) and the Web Services Interoperability Organization (WS-I).
The RandomPresent WCF Service
Yes, you read correctly…! The purpose of my WCF service is to return a random present (gift) to the client application.
As per Microsoft recommended best practice, the service contract is exposed to the outside world via an interface:
It’s possible to expose a class by applying attributes directly to the class (the attributes define the service’s runtime behaviour). However by exposing the interface to the outside world (i.e. the WSDL will map to the interface) it is possible to change how the service is implemented without necessitating modifications to the WSDL. Changing the WSDL (a file that describes the functionality of a web service) would necessitate clients downloading the WSDL and updating their proxy code accordingly. So using an interface provides a level of abstraction between the specification of the service and how the service is actually implemented, thus protecting clients from any changes to the implementation of the service.
This is the class implementation:
Here are a few notes/pointers on the most interesting aspects of this interface and it’s implementation:
- Note the inclusion of the System.ServiceModel namespace – this contains all the WCF types
- Note that I have specified a namespace for some attributes – this is crucial for a professional looking WCF service! If a namespace is not explicitly specified like this, the WSDL exposed by WCF to the outside world will contain the default namespace http://tempuri.org
WCF services can be hosted in numerous ways – for the purposes of this demo, I will host my service in IIS 8. I did this by creating a new application via IIS manager and pointing it directly to my .cs files – this is OK for a development environment but in a Production environment, you would point to an assembly.
In the root of my IIS application I created a Service.svc file, which represents my WCF endpoint and a Web.config file.
My Service.svc file looks like this:
Note that the service attribute points to the implementation of the service using the full namespace and class name. If you attempt to specify the interface in your .svc file, you will receive the following error when you attempt to view your service: ServiceHost only supports class service types.
Here is the contents of my web.config file:
A few items of interest here that I will summarise:
- Two endpoints have been specified for my service: a wsHttpBinding endpoint and a MEX endpoint. The wsHttpBinding endpoint supports the WS-* specifications which defines a common standard for remote client communication. MEX stands for “metadata interchange” so it describes how a client can communicate with the service using a WSDL file exposed to the outside world by the service (meta in this context means “about” so metadata means “data about data”).
- Note that a behaviour has been specified in the <behaviors> section that enables service metadata to be downloaded via a HTTP GET. So this enables a WSDL file to be downloaded for my service (using a web browser, for example)
- And lastly, to enable me to call my service using SOAPUI, I had to add specific details about security for my endpoint, in a <wsHttpBinding> section. So this is WS-Security configuration for my service.
Now if browse to my service using a web browser, the following web page is displayed with details about the service:
This page nicely describes how to create a proxy class for this service with help from the svcutil.exe tool, a link to a WSDL that describes the functionality of the service and then example code showing how to invoke the proxy class. However, we will be calling the service from BizTalk so won’t be requiring this information (except the handy link to the WSDL).
Finally, SOAPUI is a great tool (although sometimes a bit of a fiddle to work with WCF) for testing a service.
Invoke your web service by pointing SOAPUI to the service WSDL:
- Right click on the “Projects” node and select “New soapUI project”
- In the “New soapUI Project” dialogue box, add the location of the service WSDL and ensure that the “Create Requests” check box is ticked (this will create a sample request that can be used to invoke and test the service):
- Invoke the service by double clicking on the request and click on the green arrow to submit the request to the service. On the “WS-Addressing” tab you will need to ensure that “WS-Addressing” is enabled and that the “Add default wsa:To” is ticked. This is because the service implements wsHttpBinding, as described previously, which implements WS-Addressing (part of the WS-* specifications):
So this introduces a test WCF service that needs to be consumed by BizTalk, which will be the topic of my next post…
After exposing an external XML schema as a BizTalk WCF-WSHttp end point using the BizTalk WCF Service Publishing Wizard I fired up SOAPUI and attempted to call my web service using a test SOAP message…
However I was baffled by this obscure response:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Text xml:lang="en-US">The message with To '' cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher. Check that the sender and receiver's EndpointAddresses agree.</s:Text>
So a SOAP fault message was returned but what on earth does the explanation in the “Reason” element mean (highlighted in bold)??
The empty single quotes in the response immediately made me think that something was missing in my SOAP request but since the request was created in SOAPUI by reference to the WSDL exposed by my web service, surely everything required to call the web service would be defined?
However looks like the WSDL let me down… This article by Nabeel Prior resolved the issue: I needed to add the following
<To> element in my SOAP header:
<To soap:mustUnderstand="1" xmlns="http://www.w3.org/2005/08/addressing">
After adding this to my SOAP request message, I was able to call my BizTalk web service successfully.
The URI matches that specified in my receive location.
However surely this should have been defined in the WSDL? I would be grateful for any feedback on this.