Tuesday, 27 November 2012

BizTalk Consuming Schema/Orcehstration Service Endpoint

Error :

Cannot process the message because the content type 'text/xml;charset=UTF-8' was not the expected type 'application/soap+xml; charset=utf-8'.

Solution:

This Error could be thrown by service when there is binding mismatch between the client/server. Make sure your client application and Server is having same Binding type.
In BizTalk:
Transport Type of your Receive location must match with client.
TransportType : WCF-WSHttp/WCF-BasicHttp, must be same as client

BizTalk: Publishing Schema as WCF Endpoint Error


While working with Schema published as WCF service, after publishing schema as WCF endpoint when I tried to consume the service in client application I got the following error
“There was a failure executing the receive pipeline: "Custom.XmlReceive, Custom.BT.Pipelines, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bf32dc0ac0a61497" Source: "ConsumConfig" Receive Port: "" URI: "/Custom/Test.svc" Reason: Could not find default endpoint element that references contract 'TrimProxy.ITriming' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element”
My process flow is as follow
WCF service (Schema Endpoint) hosted on IIS server, calling BizTalk application. I was using some custom pipeline component for XMLReceive, This custom pipeline component was consuming few services, endpoint defined in  BTSNTSvc.exe.config file.
Now I got this error as my WCF Service is not able to find service endpoint setting used for Pipeline component, which is defined in BTSNTSvc.exe.config file.
Now question is “Why my WCF service is not able to read my   BTSNTSvc.exe.config file setting required for custom pipeline component?”
Answer:
As BizTalk uses two different Host process
·         BizTalkServerApplication : this host is used by all BizTalk application , This process read all required config setting from BTSNTSvc.exe.config
·         BizTalkServerIsolatedHost: All web/wcf service use this host, Know only web.config file.
As the WCF service which we have published run under BizTalkServerIsolatedHost ,This process read all configuration setting from local web.config file, When I tried to consume the published endpoint at run time it gave me above specified error, as the service is not able to find Endpoint setting required for Custom Pipeline component. And hence throw an error related to endpoint.
Solution for Error:
Just copy your required configuration setting from BTSNTSvc.exe.config and put it in Web.Config file of WCF service (IIS Virtual Directory).This will resolve your issue.

Friday, 16 November 2012

BizTalk Custom XSLT if/when

BizTalk Custom XSLT, working with “if..else” and  “when…otherwise”
When….Otherwise example:
<xsl:choose>
                    <xsl:when test="Number1">
                      <ns1:Object>
                        <ns1:Value>
                          <xsl:value-of select="Number1/text()" />
                        </ns1:Value>
                      </ns1:Object>
                    </xsl:when>
                    <xsl:when test="Number2">
                      <ns1:Object>
                        <ns1:Value>
                          <xsl:value-of select="Number2/text()" />
                        </ns1:Value>
                      </ns1:Object>
                    </xsl:when>
                    <xsl:otherwise>
                      <ns1:Object>
                        <ns1:Value>
                          <xsl:value-of select="Number3/text()" />
                        </ns1:Value>
                      </ns1:Object>
                    </xsl:otherwise>
                </xsl:choose>

If….Else example:
                <xsl:if test="Number">
                <ns1:Object>
                   <ns1:Value>
                    <xsl:value-of select="Number/text()" />
                   </ns1:Value>
                </ns1:Object>
      </xsl:if>
      <xsl:if test="Number1">
                <ns1:Object>
                   <ns1:Value>
                    <xsl:value-of select="Number1/text()" />
                   </ns1:Value>
                </ns1:Object>
      </xsl:if>

Monday, 12 November 2012

Could not enlist orchestration Object reference not set to an instance of an object.


Error :
Could not enlist orchestration  NullReferenceException exception occurred while the XLANG/s runtime enlisted a service.
Error message:Object reference not set to an instance of an object.

Cuase:

After importing BizTalk MSI file from one BT server to other server, When I tried to start BizTalk Application got this error.

 The BizTalk Application Assembly was not installed in GAC.

Solution:

GAC the BizTalk project assembly  and restart host instance, then Start you BizTalk Application.It should start now without any error.

Wednesday, 7 November 2012

WCF Fault Error from BizTalk Orchestration

Error:
Consuming WCF service from BizTalk Orchestration gives following errorReceived unexpected message type `http://schemas.xmlsoap.org/soap/envelope/Fault message
Solution :

There could be much reason to cause this type of error, like
:·         Service Response does not match with message type defined in Orchestration.
·         Service may not be giving proper response as defined.
·         WCF service security, Binding or Contract may not-match. 

And it could be also because of following simple reason

 Orchestration Logical send Port Operation name must match with BTS admin console “SOAP Action Header” Operation Name. 

Orchestration Logical Send Port Operation Name: 

  “SOAP Action Header” Operation Name. 


   The two Operation name must be same else it will give an http://schemas.xmlsoap.org/soap/envelope/Fault message while consuming BizTalk service from BizTalk Orchestration.

Tuesday, 6 November 2012

How/When to use Custom XSLT for Mapping in BizTalk

Custom XSLT in BizTalk:

·         Why to use Custom XSLT?
·         How to use/create Custom XSLT?
·         Debugging the custom XSLT.
·         Testing the custom XSLT.

Why to use Custom XSLT?
While achieving your business goal with map transformation you might come across some situation where the default provided functoid may not be smart enough to do your task and to achieve that goal of your task you need some deep level mapping changes which will lead you to write your own custom XSLT.
It’s not good practice to write custom XSLT each and every time, for simple mapping or transformation which you can achieve using available functoid then you should use that instead of writing custom XSLT. It’s good practice to write custom XSLT when you have complex mapping in your maps transformation.

How to use/create custom XSLT?
To achieve this goal, we will create a sample BizTalk application with One Orchestration, 2-schema and 0ne map. Orchestration receive the request send it to map for transforming it to response and then send back the response.
                In this case the mapping/transformation is simple but still I am using custom XSLT is just to explain “How we can use Custom XSLT?”.  We will take a simple request/response with very few fields in it so that it will be easier for us to understand.

Request Schema:

Response Schema:

Map:
With no Request- Response mapping, Mapping is done in XSLT.

 Creating custom XSLT for map:

Please follow the following steps to create custom XSLT
1.       Add 2-3 fields mapping from source schema to destination schema.
2.       Here we will add mapping between FirstName to Name and OffAddress to address node in response.

3.       Right click the map (XEmpReq_To_EmpResp.btm), click Validate map.

4.       Go to “Output Window”, you will see following Invocation Object.
Invoking component...
C:\BT_CustomXSLT\BTCustomeXSLT\BTCustomeXSLT\XEmpReq_To_EmpResp.btm: warning btm1028: The required field "EmpID" has no incoming link, constant value, or default value.
    C:\DEVELOPER\BT_CustomXSLT\BTCustomeXSLT\BTCustomeXSLT\XEmpReq_To_EmpResp.btm: The output XSLT is stored in the following file: <file:///C:\Users\ \AppData\Local\Temp\_MapData\BTCustomeXSLT\XEmpReq_To_EmpResp.xsl>
    C:\DEVELOPER\BT_CustomXSLT\BTCustomeXSLT\BTCustomeXSLT\XEmpReq_To_EmpResp.btm: The Extension Object XML is stored in the following file: <file:///C:\Users\\AppData\Local\Temp\_MapData\BTCustomeXSLT\XEmpReq_To_EmpResp_extxml.xml>
Component invocation succeeded.

5.       Click on the XSL link,

6.       Copy the file from temp location and paste it to your solution.

7.       This is the custom XSLT file created for us, it has coded mapping for FirstName and Address as we had mapped that fields in maps.
<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var" exclude-result-prefixes="msxsl var s0" version="1.0" xmlns:ns0="http://BTCustomeXSLT.EmpResp" xmlns:s0="http://BTCustomeXSLT.EmpReq">
  <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
  <xsl:template match="/">
    <xsl:apply-templates select="/s0:EmpReq" />
  </xsl:template>
  <xsl:template match="/s0:EmpReq">
    <ns0:EmpResp>
      <xsl:for-each select="Employee">
        <xsl:for-each select="Address">
          <Employee>
            <Name>
              <xsl:value-of select="../FirstName/text()" />
            </Name>
            <Address>
              <xsl:value-of select="OffAddress/text()" />
            </Address>
          </Employee>
        </xsl:for-each>
      </xsl:for-each>
    </ns0:EmpResp>
  </xsl:template>
</xsl:stylesheet>

8.       Now, we need to write mapping/coding XSLT as per our business requirement.
<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var" exclude-result-prefixes="msxsl var s0" version="1.0" xmlns:ns0="http://BTCustomeXSLT.EmpResp" xmlns:s0="http://BTCustomeXSLT.EmpReq">
  <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
  <xsl:template match="/">
    <xsl:apply-templates select="/s0:EmpReq" />
  </xsl:template>
  <xsl:template match="/s0:EmpReq">
    <ns0:EmpResp>
      <xsl:for-each select="Employee">
        <xsl:for-each select="Address">
          <Employee>
            <Name>
              <xsl:value-of select="../FirstName/text()" />
              <xsl:value-of select="../LastName/text()" />
            </Name>
            <EmpID>
              <xsl:value-of select="../EmpID/text()" />
            </EmpID>
            <Address>
              <!--<xsl:if test="HomeAddress/text() !=''">
                <xsl:value-of select="HomeAddress/text()" />
              </xsl:if>
              <xsl:if test="OffAddress/text() !=''">
                <xsl:value-of select="OffAddress/text()" />
              </xsl:if>-->
             <xsl:choose>
                <xsl:when test="HomeAddress/text() !=''">
                  <xsl:value-of select="HomeAddress/text()" />
               </xsl:when>
               <xsl:otherwise>
                  <xsl:value-of select="OffAddress/text()" />
                </xsl:otherwise>
              </xsl:choose>
            </Address>
          </Employee>
        </xsl:for-each>
      </xsl:for-each>
    </ns0:EmpResp>
  </xsl:template>
</xsl:stylesheet>

This is our XSLT with all the required business logic,
Name field is mapped with “FirstName” and “LastName”
EmpID is directly mapped with EmpID of destination schema.
For Mapping “HomeAddress”/”OffAddress”, we have used When & Otherwise. As we need to map the home address if it’s present in the request and if HomeAddress is not present then need to use OffAddress fields. So to implement this condition we have used When & Otherwise.

9.       Once XSLT development is completed, go to Map à click the area between source and destination schema, where we put the functoids , Right click à go to Properties à check property name “Custom XSLT Path :” Select your XSLT file path. (Must be inside project/solution directory).
Ex:  Custom XSLT Path : C:\DEVELOPER\BT_CustomXSLT\BTCustomeXSLT\BTCustomeXSLT\XEmpReq_To_EmpResp.xsl
10.   Right click on map(XEmpReq_To_EmpResp.btm), à Properties à Go to property Test Map Input Instance : Select your test request.
Ex: Test Map Instance : C:\DEVELOPER\BT_CustomXSLT\SampleSchema\EmpReq_output.xml


11.   Sample Request (EmpRew_Output)
<ns0:EmpResp xmlns:ns0="http://BTCustomeXSLT.EmpResp">
  <Employee>
    <Name>FirstName_0LastName_0</Name>
    <EmpID>EmpID_0</EmpID>
    <Address>HomeAddress_0</Address>
  </Employee>
  <Employee>
    <Name>FirstName_1LastName_1</Name>
    <EmpID>EmpID_1</EmpID>
    <Address>OffAddress_1</Address>
  </Employee>
</ns0:EmpResp>

12.  Now once the test instance specified, validate the instance, validated the map. Need to test map.
13. Right click Map à Click Test Map, will give response schema as output in “Output Window”.


14.   Go to “Output Window”, Click on XEmpReq_To_EmpResp_Output.xml

15.   This is what our desired output response.
<ns0:EmpResp xmlns:ns0="http://BTCustomeXSLT.EmpResp">
<Employee>
  <Name>FirstName_0LastName_0</Name>
  <EmpID>EmpID_0</EmpID>
  <Address>HomeAddress_0</Address>
  </Employee>
<Employee>
  <Name>FirstName_1LastName_1</Name>
  <EmpID>EmpID_1</EmpID>
  <Address>OffAddress_1</Address>
  </Employee>
  </ns0:EmpResp>

16.   Hence we can conclude that our map is tested and working as per our business requirement.

Debugging  XSLT :

Debugging XSLT is good tool to debug the XSL file when it’s not working as per our business or throwing some un-expected errors.
1.       To start debugging, Click on “Debug” at the top of Visual Studio à click “Start XSLT with Debugging”

2.       You must have at least one break-point in your XSLT.
3.       Then it will ask you for “Input XML Instance”, you can choose the file for which it is failing. Click Open.