BizTalk Utilities CV ,   Jobs ,   Code library
 
Go to the front page to continue learning about XML or select below:

Contents

ReBlogger Contents

Previous posts in XmlSerializer

 
 
Page 20911 of 21350

Calling a .NET Assembly from Orchestration with Schema Types

Blogger : BizTalk 2004
All posts : All posts by BizTalk 2004
Category : XmlSerializer
Blogged date : 2004 Sep 29

There I was today pointing at a customer at a past blog entry on this topic when I realized Id never got around to posting it, Doh!  Apologies for sitting on this for the last few months!

I was running some BizTalk training earlier this year and got talking about how you can pass Messages from BizTalk to a .NET component.  The typical approach is to define a parameter of XLANGMessage (Which is BizTalks in-memory representation of a message) and you can then natively pass the message from BizTalk to your .NET component.

You can then crack that XLANGMessage inside your .NET component and retrieve the underling Message body; as with everything inside BizTalk you can do this in a few ways!   Typically you dont want to load an entire message into memory (ala XmlDocument) especially if its a big message, so you might opt for a streaming approach that allows you to read parts of the message in as required.

XLANGMessage allows you to choose whichever approach suits you, e.g.:

      // XMLDocument approach
      
void MyDotNetMethod( XLANGMessage msg )
      
{
         
XmlDocument doc = msg[0].RetriveAs(typeof(XmlDocument));
      
}

      // Stream approach
      
void MyDotNetMethod( XLANGMessage msg )
      
{
         
StreamReader reader = new StreamReader( msg[0].RetriveAs(typeof(Stream) );
      
}

Now this works fine but its a bit clunky and means the interface to your .NET components isnt as clean as you would like especially if other applications are likely to consume them (XLANGMessage wont make any sense to non BizTalk solutions).

An approach that I tend to push is using XSD.EXE to generate C#/VB.NET classes based on Schemas, for those of you not familiar with XSD.EXE its a command line tool shipped with Visual Studio .NET that allows you to generate Classes or Typed DataSets based on XML Schemas, normally you might try to write code to create a XML Document (based on a schema), you end up writing pages and pages of painful code to construct a XML document by using the DOM (XmlDocument).

This is very brittle because if (heaven forbid) the schema was to change your constructing code may have to change a lot, plus its code you just dont need or want to write.  If you instead use an XSD.EXE generated class (XSD /c yourschema.xsd) you end up with a typed C# class which is dead easy to program against, e.g.

            CustomerSchemaClass Customer = new CustomerSchemaClass();
            Customer.Name = Darren Jefford;
            Customer.Address = 23 Railway Cuttings;

When you then serialize this class an XML document is created which conforms to the XML Schema automatically, if you return one of these class instances from say WebService this is all done from you, in other scenarios you can use the XmlSerializer to serialize the class into a stream (File, Network, etc.).

So, lets get back to BizTalk.  These XSD generated classes are great and easy for the developer to use so it would be neat if we could use them in our .NET assemblies that BizTalk is calling.  Obviously this may not be suitable for large messages when youre only interested in parts of it. 

We want to get to the stage where we can natively and easily exchange messages between BizTalk and .NET in such a way that it makes life easier for the developer (cracking XMLDocuments is not fun!).

This is what we want to achieve:

            xsd.exe /c CustomerSchema.xsd

            BizTalk Code:

            Message Assignment Shape: ANewBizTalkCustomerMsg = MyDotNetComponent.DoStuff( AnExistingBizTalkCustomerMsg)

            .NET Component:

      CustomerSchemaClass DoStuff (CustomerSchemaClass c )
      
{
         
...

        CustomerSchemaClass NewCustomerClass = new CustomerSchemaClass();      

         ...

        return NewCustomerClass;
      
}

After playing around with this idea I managed to very easily return one of these class instances to BizTalk without any problem, e.g.:

            .NET Code:  return NewCustomerClass

            BizTalk MessageAssignment Shape: BizTalkMessage= DotNetComponent.GetMessage();

This is great, however I couldnt get BizTalk to successfully call a .NET method passing a BizTalk message to a XSD generated class type, e.g.:

            DotNetComponent.HereIsAMessage( BizTalkMessage)

This is because BizTalk doesnt really know how to convert a BizTalk message to our serialiable class type, so cant do an automatic cast.  We end up with a halfway house, If you recall the RetrieveAs method above that allows us to get at the BizTalk message in a variety of ways we can use this to obtain the message as our serialized class, e.g.:

           CustomerSchemaClass c = MyXLANGMessage[0].RetrieveAs(typeof(CustomerSchemaClass);

You end up still requiring the XLANGMessage parameter type but it allows the Developer to use a much nicer way to access the message, you can still of course expose a non BizTalk specific interface to allow non BizTalk code to call your component with ease:

BTSSpecificCustomerMethod( XLANGMessage msg )
      {
         
CustomerSchemaClass c = MyXLANGMessage[0].RetrieveAs( typeof(CustomerSchemaClass) );

         
CustomerMethod(c);
      
}

      CustomerMethod(CustomerSchemaClass c)
      
{

      }

Hope this helps!


Read comments or post a reply to : Calling a .NET Assembly from Orchestration with Schema Types
Page 20911 of 21350

Newest posts
 

    Email TopXML