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: , ,

0 Comments:

Post a Comment

<< Home