WCF offers a lot of very powerful configuration and extensibility options – sometimes it becomes a bit dizzying.
I recently had a requirement to design a WCF service that could potentially consume many system resources (particularly, RAM) in some client scenarios. Any single call will be manageable, and concurrent calls would be manageable in some environments (but not others – the service is required to be able to process large files in a single call, but can only handle so much before running out of memory). Obviously, it would be good to find ways to split up calls to the service or for the client to sequence them, but WCF offers a very simple configuration attribute to specify that the service should run as a Singleton, processing only one call at a time:
Problem solved, right? Now what if a particular environment…
This error is typically harmless, but can result when the XML Disassembler encounters an empty Envelope message instance that’s formatted like this:
instead of this:
BizTalk chooses to make a semantic difference between these two instances, and process the second one fine (publishing no messages), but raising an exception like this for the first:
There was a failure executing the response(receive) pipeline: “…” Source: “XML disassembler” Send Port: “…” URI: “…” Reason: Unexpected event (“eos”) in state “processing_header”.
This can happen particularly when using an XmlProcedure or XmlPolling from SQL – if the resultset is empty, the adapter will publish this message. While this behavior may be desirable (and can frequently be avoided by ensuring you have good Data Available statements on your polling ports, and only call XmlProcedures with valid parameters/at valid times), it can also generate a lot of alarming errors….
MSDN provides an example of INSERTing large data into SQL Server, leveraging the WCF-SQL adapter’s built in FILESTREAM capabilities. However, it’s also possible to leverage the transaction enlisted by the WCF adapter in a custom pipeline to pull FILESTREAM data out of SQL Server more efficiently than the more common SELECT … FOR XML query which simply grabs the FILESTREAM content and stuffs it into an XML node in the resulting document.
Imagine, for example, you had a large document of some sort (XML, Flat File, etc.) to store in SQL Server that BizTalk would need to process from a FILESTREAM table defined like so:
The tradeoff here is losing the typed XML data in favor of more efficient storage and access to larger file objects (especially when the data will, on average, be large). This can make a vast difference if you have…
With the ESB Toolkit, BizTalk provides an excellent framework for handling exceptions that occur throughout the ESB. There are many built in facilities that are as simple as checking off a box to route failed messages to the portal, and within orchestrations you can easily build ESB Exception messages in catch blocks and route them to the portal as well.
However, these only apply if a message actually makes it to a pipeline or orchestration. For WCF SQL Polling receive locations, it’s possible that no message will ever make it to the pipeline – for example, if the procedure causes an exception to occur (perhaps by a developer intentionally using THROW or RAISERROR), the adapter will write the exception to the event log without providing a message for any pipeline or orchestration processing. Checking “suspend message on failure” doesn’t offer any…
I wrote previously (here) about using SQL Server Profile to capture and debug SQL calls from BizTalk. This method works well when there are no errors actually calling the procedure (but you want to tune the procedure using ‘real’ data from BizTalk). However, it’s not as much help when BizTalk can’t call the procedure at all – because of an invalid conversion, or a malformed table type, or some other errors in the procedure that prevent the procedure from actually being run. Either no event will get logged in the Profiler, or you will see only the stored procedure name but no parameters (because BizTalk realizes the procedure won’t be able to correctly execute).
Consider the following scenario: you have a tested BizTalk Orchestration that effectively takes a parameter (say, a message identifier) and returns the message from a database for consumption. Now you want to expose a WCF Service for consumers of that orchestration to use. While you could design a SOAP based interface, a simple RESTful interface that accepts a GET verb would do the trick more elegantly (and in a way that would be much easier for clients to work with). It also may meet a requirement when you already have clients that expect a RESTful interface for data retrieval.
There’s plenty out there on handling REST GET requests using BizTalk Orchestrations as a consumer:
Unfortunately, the same can’t quite be said about handling REST GET requests as a provider; there are resources:
…but this side of the equation tends to focus on POST and PUT…
On a recent engagement, I was developing a BizTalk 2013 solution that received XML-based data from several sources and ultimately inserted rows into a SQL Server database using a stored procedure. An additional requirement was that the database connection had to be dynamic.
As with most development, everything worked fine in the development environment and even in initial UAT testing. A timeout issue started to appear intermittently as the size of the data being processed increased and the content of the database grew. Rerunning the same test data through would often complete successfully. The details of the message logged to the Windows Logs was:
A message sent to adapter “WCF-Custom” on send port “WCF.Timeout_188.8.131.52_WCF.Timeout.ProcessDataToSQL_Dyn_WCFTest_c495b1996f35b303″ with URI “mssql://xxxx//Test?” is suspended.
Error details: System.Data.SqlClient.SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. —> System.ComponentModel.Win32Exception…
Typed Polling with WCF Adapters
It is very common to have a requirement in middleware design where we have to query SQL tables and retrieve some data when certein conditions are met.
The WCF-based adapters available with the BizTalk Adapter Pack enable the adapter clients to receive data-change messages from the SQL Server database(s). The adapter(s) support receiving “polling-based” messages wherein the adapter executes a specified SQL statement (SELECT statement or stored procedure), retrieves or updates the data, and provides the result to the adapter client at regular intervals of time. The adapters supports three types of polling:
Weakly-typed Polling (also called Polling),
Strongly-typed Polling (also called TypedPolling)
Xml-Polling polling using statements or procedures that include a FOR XML clause
For more information about the different types of polling, see Polling SQL Server by Using the SQL Adapter with BizTalk Server (http://go.microsoft.com/fwlink/?LinkId=221195).
Assumptions and prerequisites
This document is…
Last week month (sorry about that!), I wrote a post about using MABS to access a LoB system (in the example, SQL Server) behind several layers of firewalls (here).
We looked at the following tasks
Creating the BizTalk services
Setting up BizTalk Adapter Services in a local (or IaaS) environment to run a stored procedure in SQL Server
Creating a sample table and stored procedure
Creating a ServiceBus namespace with ACS
Create the Relay to the LOB system
Creating an EAI bridge to access the LoB system
This week, we’ll look at these tasks:
Testing and debugging the bridge with a Visual Studio add on
Writing a custom component to call the LoB adapter in a EAI Bridge Stage and parse the response
Having the component send an email notification using an Office 365 server
I’m currently working on a solution that exposes a BizTalk Orchestration as a RESTful webservice using WCF-WebHttp. Upon successful processing of the message, the service returns binary data for the client to download. However, if the processing fails, I wanted the service to return application/json data with an error message that would be suitable for consumers – I did not want Stack Traces or other internal details to be provided that could potentially be used by malicious consumers. Further, I wanted to ensure this information was sent in the same session.
Initially, I created a schema with my sanitized error information, set the Fault Operation Message Message Type to that schema, and enabled “Include exception details in faults.” While this did end up including my custom error message, it also included the extra information I was trying to avoid. It also…