BizTalk custom XML validation to get error summary
Introduction
This article explains step by step procedure to extend the XML validation with BizTalk.
It is always good to validate the incoming document against the schema in BizTalk for validation and errors instead of leaving it as it is and handling them later.
We can validate the incoming document in BizTalk using two ways.
- Using XMLReceive pipeline component
- Using XmlValidate pipeline component in the validate stage of custom receive pipeline.
The issue with the above methods is it writes first error message for field validation failure which end up having single error at any point of time in log/event viewer for a single document.
It would be nice to get all these errors as a summary and write a single error message to log with all the validation failures.
The aim of this article is to get a single summary of all validation errors and write to event viewer.
I personally experienced this scenario in one of my recent projects and what a waste of time to fix each error after it is being written to log. So instead we can fix all the errors in one go if we can get the summary of all errors in a single message.
Problem Statement:
BizTalk out of box validation will raise only the first error with validation and not the error summary with all errors in it.
Let’s get started with creating BizTalk artefacts for this assignment.
Default Validation
Create a new empty BizTalk server project with name “CustomXMLValidation”
Add a customer schema with basic customer fields and save as Customer.xsd
Create a receive pipeline with name “Recv_ExtendedXmlValidator.btp”. Open the pipeline and go to Toolbox and drag the “XML disassemble” into Disassemble stage and XML validator to Validate stage. Click on the XML validator and go to properties and set the Document schemas as customer schema as shown in the picture.
** **
Right click on “CustomXMLValidation” BizTalk project and deploy to see what the out of box behaviour with validation inside BizTalk.
After deployment go to BizTalk server admin console and create one receive port to pick the input XML file and one send port to save the same file to folder if there are no errors.
Create a FILE receive port with name “Recvport_Inputxml”
Create a FILE send port with filter on Receive port name “Recvport_Inputxml” and pipeline as pass through.
Let’s try first configuring the receive location with default XML Receive pipeline and see the output.
** **
Drop the customer input XML file in to the folder. The input message is shown in the picture below and the message has minimum two errors. ID is not 36 in length and customer number is not 10 digits.
I dropped the message into In folder and message is created into Out folder by send port. So literally no error as there is no validation performed with default XML Receive pipeline. If we open the XML receive pipeline properties Validate Document property set to False hence no validation is performed.
We can set the Validate Document to true but it also expects Document specNames to be specified with schema name to perform the validation. Our idea is to make this solution as generic to suit for any schema instead of hard coding to one schema hence I have not specified.
Now let’s try the second approach by configuring the receive pipeline “Recv_ExtendedXmlValidator” that we created in the projects that includes XMLdisassemble and XML validator components.
** **Now let’s again drop the message into In folder.
Here is the outcome
- There is no message in the Out folder that proves there is some error with validation
- Error is being written to Event viewer
There was a failure executing the receive pipeline: "CustomXMLValidation.Recv_ExtendedXmlValidator, CustomXMLValidation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9b15b7912281dab2" Source: "XML validator" Receive Port: "Recvport_Inputxml" URI: "D:\JB_Testing\CustomXMLValidation\In\.xml" Reason: The XML Validator failed to validate.
Details: The 'ID' element is invalid - The value 'asd' is invalid according to its datatype 'String' - The actual length is less than the MinLength value..
The above error shows only the first error message not showing all of the errors.
Solution Design
Create a custom xml validation pipeline component that does the XML validation
- Register the above component in the toolbox
- Create a pipeline that uses this custom XML validation component in the validate stage.
- Create a common orchestration that takes any message as xmldocument and executes the receive pipeline and throws the error message to the caller.
Create a custom xml validation pipeline component
Add a new c# project to the “CustomXMLValidation” solution.
The execute method of pipeline component looks like this
And validate () function is looks like this.
Register the pipeline component in the toolbox
Build the pipeline component project and deploy to GAC
Open the “Recv_ExtendedXmlValidator.btp” pipeline and open Toolbox. Right click on Tool box and select Choose Items
Select BizTalk Pipeline Component tab and search for the component in the list and select “ExtendedXMLValidor” and click OK.
Create a pipeline that uses this custom xml validation component in the validate stage
As we have already created the pipeline “Recv_ExtendedXmlValidator.btp” we can re-use the same.
Drag this component from Toolbox to validate stage by removing the previously added XML validator component.
Create a common validation Orchestration
Add reference to “Microsoft.BizTalk.Pipeline.dll” from “CustomXMLValidation” project and we can browse to this file with the below path
C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\PublicAssemblies\Microsoft.BizTalk.Pipeline.dll
Add a new orchestration “Proc_ValidateXml.odx” to the project that executes the pipeline to do the validation.
In the orchestration View pane, lets create an In parameter with name “xmlToValidate” which is the actual message to validate and the data type is XMLDocument
Add a scope to the orchestration and attach as exception handler of type “Microsoft.XLANGs.Pipeline.XLANGPipelineManagerException”
Create an orchestration variables for throwing exception
Variable name : varException
Type : System.Exception
Drag an expression shape to the scope and give the below code to execute the validation pipeline.
Microsoft.XLANGs.Pipeline.XLANGPipelineManager.ExecuteReceivePipeline(
(typeof(Recv_ExtendedXmlValidator)), xmlToValidate);
If there are any validation errors the exception is caught in the catch block and throw the same exception to the caller.
Drag an expression shape and give the below code
varException = new System.Exception("Schema validation Error:" + exSchemaValidation.Message);
Drag a “Throw Exception” shape and configure the Exception Object as “varException”
Final orchestration looks like below
Now we have our common orchestration is ready and can call this orchestration from any orchestration passing the message as XMLDocument using “Call Orchestration” shape.
Create Orchestration that gets the input file
Let’s create an orchestration that picks the input file from folder and perform the validation by calling the common validation orchestration using “Call Orchestration” shape. If there is any validation error move the file to separate “Error” folder for monitoring.
Create a new orchestration to the project with name “ProcessFile.odx”
Create the below orchestration messages
Message_In of type CustomXMLValidation.Customer
xmlToValidate of type System.Xml.XmlDocument
Adda scope “Scope_ValidateMessage” and attach an exception handler to the scope.
If there is any validation error control comes to the catch block, log the error and move the file to separate error folder using send shape.
In the scope add an expression shape to convert the input message entity to XML document to pass it to common orchestration.
After this drag a call orchestration shape and pass the xmlToValidate as input message.
** **
After deploying lets drop the same error input into In folder and below is the outcome
File moved to Error folder
Below error message is being written to event viewer with all the errors.
Error Occured.FileName : D:\JB_Testing\CustomXMLValidation\In\Customer_Input.xml: Schema validation Error:There was a failure executing pipeline "CustomXMLValidation.Recv_ExtendedXmlValidator". Error details: "XML validation failed for a "http://CustomXMLValidation.Customer#Customer" message, with a message ID of "4cdd4bad-5b98-4ce2-b5bc-3e52a95cd77a". Error Message(s):
Line: 2, Position: 12, Error: The 'ID' element has an invalid value according to its data type.
Line: 4, Position: 30, Error: The 'CustomerNumber' element has an invalid value according to its data type.
Deployment
- Download the zip file from TechNet gallery using below link which contains the solution and bindings files https://code.msdn.microsoft.com/BizTalk-custom-xml-805b0e70
- Unzip to folder
- Open CustomXMLValidation.sln, build and deploy the project
- Go to BizTalk server admin console and import the bindings file “CustomXMLValidation.BindingInfo.xml”
Running the sample
Drop the sample input file “Customer_Input.xml” into In folder and the file will be moved to Error folder as there are validation errors in the file.