Yossi Dahan [BizTalk]

Google
 

Tuesday, September 23, 2008

Calling a web service with an enumeration parameter from BizTalk Server

This was waiting in the drawer for ages now and somehow never quite made it onto the blog...

Most of our web service's methods take one enum or another, which generally works well, but it did take us a bit of experimentation to figure out how to call them from a BizTalk orchestration; here are the details -

Take for example this version of a HelloWorld web service: 

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
public class Service1 : System.Web.Services.WebService
{
   [WebMethod]
   public string HelloWorld(MessageType message)
  {
     return "Hello World; " + message.ToString();
   }

   [System.Xml.Serialization.XmlType
       (AnonymousType=false,Namespace="http://MyNamespace")]
   public enum MessageType
   {
     Hello,
     GoodBye
   }
}

(I’ve made the enum an anonymous type and given it a namespace to represent real world scenarios from my experience, see http://www.sabratech.co.uk/blogs/yossidahan/2007/02/anonymoustypes-and-serialization.html )

Looking at the test page for this web service you get an example request that looks like this –

POST /Service1.asmx HTTP/1.1
Host: localhost
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/HelloWorld"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">  <soap:Body>
    <HelloWorld xmlns="http://tempuri.org/">
      <message>Hello or GoodBye</message>
    </HelloWorld>
  </soap:Body>
</soap:Envelope>

Notice how the parameter name is message (as the name of the parameter of the method?)

And indeed if I use HttpAnalyzer to examine the traffic “on the wire” I can see the request message going through as –

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
    <HelloWorld xmlns="http://tempuri.org/">
      <message>GoodBye</message>
    </HelloWorld>
  </soap:Body>
</soap:Envelope>

Which makes perfect sense.

Moving to a BizTalk project - I add a web reference from my BizTalk project to generate the proxy i.e port type, schemas, message types etc.

The request message-type generated has a part for my enum, as expected, however, unlike what I'd expected,  to pass an enum value to the web service, you don't wrap the enum value in the parameter name as it appears on the wire (and in the test page), which would have been -

      <message>Hello</message>

but instead the value is wrapped in an element that matches the enum type definition, as such -

<ns0:MessageType xmlns:ns0="http://MyNamespace">Hello</ns0:MessageType>

This is quite obvious once you look at the schema that got generated -

<xs:schema xmlns:tns="http://MyNamespace" elementFormDefault="qualified" targetNamespace="http://MyNamespace" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="MessageType" type="tns:MessageType" />
  <xs:simpleType name="MessageType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Hello" />
      <xs:enumeration value="GoodBye" />
    </xs:restriction>
  </xs:simpleType>
</xs:schema>

but I just didn't bother initially, expecting to need to build the parameter the way it appears on the test page.

So in order to call the web service from a BizTalk orchestration you would need to create a message with the correct xml in an expression shape;

I use (with doc being a variable of type XmlDocument) -

doc = new System.Xml.XmlDocument();

doc.LoadXml("<ns0:MessageType xmlns:ns0=\"http://MyNamespace\">Hello</ns0:MessageType>");

and then I assign it to the request

WSRequest.@message =   doc;

(where WSRequest is a message of the web message type generated as part of the add web reference procedure, and @message is the part that was created to represent the enum parameter)

Labels: , ,

Saturday, September 13, 2008

Yet another example for a service's / xml bad design?

One of my clients have been using this 3rd party's software for some time now (I won't name neither organization for obvious reasons).

In their organisation both BizTalk and this software are key components and so they both play part in many scenarios.

Unfortunately, and quite surprisingly, this 3rd party's software doesn't have have any adequate support for integration and the main way to interact with it is pushing some data into 'import tables' in the software's database and then running some EXE to process them. quite horrendous.

To make matters worse this EXE can only allowed to run once at any single time so most implementations require some form of queuing and singleton pattern.

Recently that third party released a version with *some* support for web services, and so, excited by the great news the development team went on to implement a process using the newly introduced web service.

The service that had been exposed relates to the product's reporting features - users can create custom reports using the product's UI and then, using web services, export the result of these queries.

I would have expected, based on past experience, a generic schema in the WSDL that would describe a report's output, irrespective of the fields returned, something like -

<row>

<column fieldName=".."></column>

<column fieldName=".."></column>

.

.

</row>

But the vendor's schema included some generic field from their domain (report name, time of execution, etc.) and then rows and fields based on the specific report generated.

Because the report's structure is not known at design time its fields do not exist in the WSDL, instead a report node exist with an xs:any declaration to include the actual report's contents.

Personally I prefer to avoid xs:any if possible, and I think a schema describing a generic report's result could have been created, but that's not the main problem; the main problem, in my view, is that the fields added underneath the report element (as well as the report element itself), which are generated by the application, all belong to the same namespace.

Because they could not predict the names report designers will use for fields it was more than possible to create an element with duplicate meaning which is a bad idea overall and also causes quite a bit of headache when one needs to create schemas for BizTalk to accurately describe the response of such a service.

One thing I will grant them is that they have though of defining LAX validation for the report, so duplicate elements will not cause validation errors.

Labels: , ,

Sunday, September 07, 2008

Where did it go?

You've created your map, selected your schemas and (if you're anything like me) set the custom xsl path to the file containing the xsl script you've worked hard to create.

You then go to the orchestration and add a transform shape, but when you select the messages the designer notices you have selected different types to those in the map and kindly offers to change the types in the map for you; you think - how generous and kind...

However, it goes one step further, and without much notice, it is re-setting the custom xsl path (to nothing, that is), which would result in an empty output from the map when you run the process and one very frustrated BizTalk developer.

To be fair it does suggest that "some links may be lost" before doing all of that and ask for confirmation, and of course you can see their ("they" being Microsoft) side of the story - they assume that if you change types in the map the links/xsl may no longer be relevant...but I would argue that if I chose to use the same map, then they probably are, otherwise I'd start a new one....

Labels: , , ,

Next UK SOA/BPM user group meeting

The next UK SOA BPM user group meeting is scheduled for the October 14th in London; check out the details in Mike's blog.

Friday, September 05, 2008

BizTalk get's a new logo (oh - and a new version too!)

BizTalkSvr09_h_rgb_r

Microsoft has announced the next major version of BizTalk - BizTalk Server 2009.

Planned to be released 'H1 CY09', the new version, previously referred to in some circles as BizTalk "R3", adds support for the latest Microsoft stack - Windows Server 2008, SQL Server 2008, Visual Studio 2008, .net framework 3.5 and TFS 2008 - including automated builds and continuous integration as well as virtualisation using Hyper-V.

There are also further investments in B2B (EDI, SWIFT), RFID, enhanced LOB adapters and support for UDDI 3.0

Next CTP is planned for sometime in the last quarter of this year, while previously Microsoft announced that BizTalk '6' will be part of the 'Oslo' wave this version released ahead of 'Oslo', which is great news for all of us longing to move to the latest platform with BizTalk Server.

See the announcement here

Labels: ,