none
Biztalk 2010. Xml to json conversion pipeline component queries RRS feed

  • Question

  • Hi

    I am using a custom pipeline component for xml to json conversion in the send pipeline of receive location.

    Below is the code used in execute()


    • Edited by Suja Balan Wednesday, October 26, 2016 2:12 PM
    Thursday, July 14, 2016 6:29 AM

Answers

All replies

  • Hi Suja

    Why not use the JsonConvert.SerializeXmlNode method, instead of JsonConvert.SerializeObject method that you are using . It takes an XmlDocument and returns JSON string. No need to specify .NET types-

    XmlDocument doc = new XmlDocument();
    doc.LoadXml(xml);
    string jsonText = JsonConvert.SerializeXmlNode(doc);

    http://www.newtonsoft.com/json/help/html/convertingjsonandxml.htm

    The code in the Execute method can look something like this (not tested)-

    XmlDocument message = new XmlDocument();
    message.Load(pInMsg.BodyPart.Data);
    
    string jsonText = JsonConvert.SerializeXmlNode(message);
    var stringBytes = System.Text.Encoding.UTF8.GetBytes(jsonText);
    
    MemoryStream outStream = new MemoryStream();
    outStream.Write(stringBytes, 0, stringBytes.Length);
    outStream.Position = 0;
    pInMsg.BodyPart.Data = outStream;
    pContext.ResourceTracker.AddResource(outStream);
    return pInMsg;



    Thanks Arindam



    Thursday, July 14, 2016 6:54 AM
    Moderator
  • Check for events around the error message - you will find the source that is throwing the error.

    I suspect that the XML being passed to the SerializeXmlNode method is not in a format that JSONConvert is handling well.

    Also, what is the method that you are using now?


    Thanks Arindam

    Thursday, July 14, 2016 7:28 AM
    Moderator
  • Without your exact code it is difficult to follow along the trace you have shared.

    Thanks Arindam

    Thursday, July 14, 2016 7:59 AM
    Moderator
  • Ok I see what is happening - there is no issue with your pipeline component - it's working fine!

    It is again the webHttp binding that is probably causing this. Seems that it is trying to process/parse the JSON content and failing. 

    Try using the PassThruTransmit pipeline as the Send pipeline, what do you get back in Fiddler?

    As mentioned on the other thread yesterday, try to setup everything using FILE adapter - so that you can test these pipeline components more easily. Once you confirm they are working, you can switch to either HTTP/webHttp adapter.


    Thanks Arindam


    Thursday, July 14, 2016 8:09 AM
    Moderator
  • Yes you can just test using pipelines only.  So place JSON content file in receive location path. You can set pipeline in RLoc to your custom pipeline JSONtoXml.  Create a FILE adapter SendPort that subscribes to this Receive Port on the Filter BTS.ReceivePortName property. Do you get the converted XML in the SendPort file path?

    Also try the reverse scenario.


    Thanks Arindam




    Thursday, July 14, 2016 8:34 AM
    Moderator
  • It depends on how you want to test.

    If you have the Oracle response XML with you, you don't need to use orchestrations to test this.

    You can test this using just Ports/pipelines:

    1) For JSON-> XML: Create a ReceivePort/ReceiveLocation with the custom pipeline that converts from JSON to XML. Create a SendPort with PassThrough pipeline with a filter on BTS.ReceivePortName = <your ReceivePort name>. Use FILE adapter on all ports (for path specify a local path on BizTalk server. You have to drop the JSON content file in the ReceiveLocation path.

    Refer the link I shared earlier on one of your threads yesterday.

    2) For XML->JSON: You need the Oracle response XML. The ReceivePipeline will be the custom pipeline you created for XML-> JSON conversion. Other steps will be same.


    Thanks Arindam


    Thursday, July 14, 2016 10:00 AM
    Moderator
  • The host instance account needs Full Access permission to the Receive Location path/folder.

    Thanks Arindam


    Thursday, July 14, 2016 11:02 AM
    Moderator
  • Why are you making things so difficult for yourself and the group?  IIS, remote locations?

    You need to test things with the simplest configuration possible.

    Thursday, July 14, 2016 12:13 PM
    Moderator
  • Ok so your component(s) are working fine. An idea since you are not being able to setup the webHttp binding.

    Try to use the HTTP adapter on a 2-way ReceiveLocation/ReceivePort instead - same orchestration can be used. Since your solution just needs a HTTP POST to work, it will suffice in your scenario. In the ReceiveLocation, use your custom pipelines, I believe your solution will work.

    Some links on how to create a HTTP adapter based ReceiveLocation in BizTalk (there are some configuration steps in IIS that you need to take care of as well)-

    http://rohitt-sharma.blogspot.in/2011/03/biztalk-tutorial-part-7-using-two-way.html

    https://connectedenterprise.wordpress.com/2011/11/22/configure-an-http-receive-location-in-biztalk-2009/

    https://msdn.microsoft.com/en-us/library/aa559072.aspx

    https://msdn.microsoft.com/en-us/library/ee267543(v=bts.10).aspx


    Thanks Arindam





    Thursday, July 14, 2016 12:49 PM
    Moderator
  • Two options-

    1. Use a map in the ReceivePort, as an Outbound Map. The Map can use custom XSLT as shown in this thread -

    <?xml version="1.0" encoding="utf-8"?>  
    <xsl:stylesheet version="1.0" 
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  
     
      <xsl:output method="xml" indent="no"/>  
     
      <xsl:template match="/|comment()|processing-instruction()">  
        <xsl:copy> 
          <!-- go process children (applies to root node only) --> 
          <xsl:apply-templates/> 
        </xsl:copy> 
      </xsl:template> 
     
      <xsl:template match="*">  
        <xsl:element name="{local-name()}">  
          <!-- go process attributes and children --> 
          <xsl:apply-templates select="@*|node()"/>  
        </xsl:element> 
      </xsl:template> 
     
      <xsl:template match="@*">  
        <xsl:attribute name="{local-name()}">  
          <xsl:value-of select="."/>  
        </xsl:attribute> 
      </xsl:template> 
     
    </xsl:stylesheet> 
     
     

    Another better example of the map that does not need custom XSLT-

    http://richardhallgren.com/removing-xml-namespaces-revisit/

    2) Custom pipeline component that is placed before your XMLToJson component. The component will remove the namespaces/namespace prefixes from the XML output from orchestration. Sample here with link to download-

    https://biztalktalk.wordpress.com/2012/06/26/changing-removing-document-namespaces/


    Thanks Arindam


    Thursday, July 14, 2016 3:18 PM
    Moderator
  • Please open a new thread.

    Thanks Arindam

    Friday, July 15, 2016 6:25 AM
    Moderator
  • The exception is InvalidOperationException - it can mean a lot of different things. To which process are you attached currently? Which adapter?

    Thanks Arindam

    Friday, July 15, 2016 10:09 AM
    Moderator
  • Hi

    Is this a new error? Wasn't the custom pipeline component exiting without errors yesterday?

    The error is probably being thrown from the webHttp binding. For which the workaround suggested yesterday to check with the HTTP adapter(see above). Is the webHttp behavior added to EndPoint behaviors on the adapter? If yes, can you remove it and check?


    Thanks Arindam

    Friday, July 15, 2016 10:26 AM
    Moderator