Thursday 15 January 2009

How to send Custom Soap Headers from BizTalk


Hi, I have been searching for an good article which shows the step by step development approach for sending a Custom Soap Headers from Biztalk. I found a couple of Microsoft blogs but its not very clear to me.

I just started my invention to find the right direction to accomplish this task today. I thought this would a help others to work with custom soap adapters.

The first Step is to develop an Webservice which had an additional SOAP header to the Webmethod. I hope you are expert in writing .net code to build an simple Webmethod.Here is my sample WebMethod and custom Soap header.

Now lets start work on Biztalk Part

First Step is to create a Similar Soap Header Property Schema at biztalk and set the couple of property to make use of Custom Soap header. How you are going to achieve this?
Add webreference to your Biztalk Application. You can find the Reference.XSD Schema with custSoap header.

Steps to Create Soap Header Schema:
Create a Property Schema and rename to any(not necessary to rename) Just to keep this schema as more understandable. I renamed it as SoapHeader.xsd
Rename the “Property1” element to your Custom soap Header Class name and set the properties as mentioned below.
Ex: In my above .net Code my Soap header class name is “CustAuthHeader
Schema property:
TargetNamespace=http://schemas.microsoft.com/BizTalk/2003/SOAPHeader
CustAuthHeader Property :
PropertySchemaBase = MessageContextPropertyBase


Assign SoapHeader Property values at Orchestration level :
As soon as you add web reference you can find Reference.xsd file which contain the SoapHeader elements. Here you have 2 options
  1. You can use Reference.XSD schema to send the UserName, Password
If you don’t find Reference.xsd then Create your Own schema and maintain Rootnode same as SoapHeader Class name and Input params as Elements.

Here I am using Reference.xsd schema to test this sample.
Before you call webMethod you need to pass the Soap Headers to the WebService Request. The orchestration Steps are

  1. collect the Input values from the Inbound Schema
  2. map the InputSchema to Reference.xsd Schema
  3. Assign Reference Schema Values to SoapHeader Property
  4. Call Webservice and get Response

Here step1, 2 and 4 is easy. What about the step 3 ? what you need to write at Assignment Shape ?
Here is the code
vxmlObj = new System.Xml.XmlDocument();
vxmlObj= WsReferenceMsg;
SoapHeaderWsRequestMsg(SOAPHeaderTest.CustAuthHeader)=vxmlObj.InnerXml.ToString();
Note: SOAPHeaderTest.CustAuthHeaderĂ  ProjectName.YourPropertySchemaRoot element.

Your final Orchestration should look like above image.
You can reach me at : raj.webjunky@yahoo.com

Monday 5 January 2009

Custom Soap Exception Detail Propty -Work with BizTalk

How to make use of Custom SOAP error Detail property in BizTalk ?
Today I start this artical with showing a property of Soap Exception. Just have a look at the below image. Have you ever played around with Detail Propery provided by SoapException? If your anwer is "Yes" then jump to Biztalk part below the Webservice code and see how to handle the Detail property at biztalk level. Otherwise check the below code for detailed programming for Custom Soap Exceptions. ( Build a Detail property using Csharp Code).
.

I have written a simple webservice (webmethod) which accepts two input parameters and check the authentication. If success then returns the Bool value of "True" else raise the Cusom Soap Error Message.

WebService Code
[WebMethod]
public bool CheckAuthentication(string UserName , string Password)
{ if (UserName == "TestUser" && Password == "TestPwd")
{ return true; }
else
{
throw RaiseCustomSoapError("AuthenticationCheck","","101","User is not Authorize person to access this site" "CustomSOAPException");
}
}
________________________________________________________________________________________________________
public SoapException RaiseCustomSoapError(string NameofActor, string wsNamespace, string errNumber,string errMsg, string errSource)
{
XmlQualifiedName tmpfaultCode = null;
tmpfaultCode = SoapException.ClientFaultCode;

XmlDocument xmlDoc = new XmlDocument();
XmlNode rootNode = xmlDoc.CreateNode(XmlNodeType.Element,SoapException.DetailElementName.Name,SoapException.DetailElementName.Namespace);
XmlNode errorNode1 = xmlDoc.CreateNode(XmlNodeType.Element, "Errors", wsNamespace);
XmlNode errorNode = xmlDoc.CreateNode(XmlNodeType.Element, "Error",wsNamespace);
errorNode1.AppendChild(errorNode);

XmlNode errNumberNode = xmlDoc.CreateNode(XmlNodeType.Element, "ErrorNumber", wsNamespace);
errNumberNode.InnerText = errNumber;

XmlNode errMsgeNode = xmlDoc.CreateNode(XmlNodeType.Element, "ErrorMessage", wsNamespace);
errMsgeNode.InnerText = errMsg;

XmlNode errSourceNode = xmlDoc.CreateNode(XmlNodeType.Element, "ErrorSource", wsNamespace);
errSourceNode.InnerText = errSource;

errorNode.AppendChild(errNumberNode);
errorNode.AppendChild(errMsgeNode);
errorNode.AppendChild(errSourceNode);
rootNode.AppendChild(errorNode1);

//Constructing the exception
SoapException soapEx = new SoapException(errMsg, tmpfaultCode, NameofActor, rootNode);
return soapEx;
}
When you select soapEx.Detail property will retun the XML Structure of Error Details as mentioned in below format.
Custom Error Message Structure



BizTalk Code
Summary of Orchestration Flow : BizTalk receives the Inbound XML File which has username,password and Sends the same to Webservice method (CheckAuthentication) "Request"
If the UserName and password is valid then Wesbservice return the Success status of "True" value and you need to build the output Message and send to Destination Location.
Incase of Failed Authentication Webservice Throws Custom SOAP Exception. Biztalk will pick this Exceptions at SOAP Exception block (System.Web.Services.Protocols.SoapException) using Detail Property.

Inbound and Outbound Schemas:



Orchestration Flow


Write the below code at Assign Error Detail ( Assignment Shape) Code

vErrDetails = soapEX.Detail.OuterXml.ToString();
vXmlObj = new System.Xml.XmlDocument();
vXmlObj.LoadXml(vErrDetails);
GenMsg = vXmlObj;

vXmlObj2= new System.Xml.XmlDocument();
vXmlObj2.LoadXml(" Your generated output Schema structure");

OutputMsg = vXmlObj2;
xpath(OutputMsg,"//Errors") = xpath(GenMsg,"//Error");



For success Output message Error node would be empty and for the Failure (Custom Soap Error Detail property message) Error node filled with details.


you can reach me at raj.webjunky@yahoo.com