Consuming Web Services in BizTalk Without Web Reference

Twice last week, I received WSDLs to consume that BizTalk didn’t like. That is, when I would try and load the WSDL via Add Web Reference, I’d get an error like the following:

Could not generate BizTalk files. Unable to import WebService/Schema. Unable to import
binding ‘WebServiceBinding’ from namespace
‘http://xmlns.company.com/interface/project/SubmitSubjectImpl’. Unable to import operation
‘SubmitSubject’. The element ‘http://xmlns.company.com/project/subject:subjectrequest’ is
missing.

I also tried from a “regular” .NET project, and no luck. One of the WSDLs used “imports” (a no-no for importing the web reference), and I’m convinced that the other WSDL’s problem was indeed namespace based. Now in both cases, I didn’t have the luxury of telling the WSDL owner to make changes. So how to get around this? Inspired a bit by Jon’s blog, I decided to try using the .NET Framework tool wsdl.exe. For the WSDL using “imports”, I executed WSDL.exe passing in the WSDL, and parameters for each schema used. Sure enough, I was able to generate a valid C# proxy class. The other offending WSDL was also successfully processed using WSDL.exe. As a result, I now had a proxy class needed to consume this service.

Next I added that proxy class to a .NET class library, built, and GAC’ed it. Next I used the provided schema files to create messages in a BizTalk orchestration corresponding to the request and response message. Finally, I connected this to a “two way” port in the orchestration.

After deploying the BizTalk project, I had to configure the necessary SOAP send port. Unlike a “regular” SOAP send port, I was not using an orchestration port as the proxy. Instead, I am now pointing to the proxy class generated by WSDL.exe. On the Web Service tab of the SOAP port, I chose the assembly and method I needed.

Now assuming everything was set up right, I should have been able to call the web service with no problem. But, if we stick with the base assumption that I’m a total meatball, of COURSE it didn’t work the first time. Instead I got this …


A message sent to adapter “SOAP” on send port “Company.Dept.Project.SendTibcoSvc.SOAP” with URI “http://machinename:1234/ProcessDefinitions/WebService” is suspended.
Error details: Failed to serialize the message part “subjectrequest” into the type “subjectrequest” using namespace “http://xmlns.company.com/project/subject”. Please ensure that the message part stream is created properly.

Obviously the proxy couldn’t serialize my XML message. So, I output the message I was sending to the port, and tried validating it against my schema. Sure enough, I got validation errors like The string ” is not a valid XsdDateTime value. and The string ” is not a valid Integer value.. So, I fixed the source problems, and validation succeeded. Finally, when calling the service again, everything worked perfectly.

Moral of story: you can consume web services WITHOUT using a “web reference” as long as you can build the proxy class. Good stuff.

Technorati Tags: ,

24 Responses to “Consuming Web Services in BizTalk Without Web Reference”


  1. 1 Donnie Hale August 9, 2007 at 12:35 pm

    The technique in this article may help me solve a problem I’m having, but as a BizTalk newbie, there are a couple of things that aren’t quite clear. I’m with you up through running wsdl.exe and building/gac-ing an assembly with the proxy class(es). After that…

    - You used which provided schema files to create request / response messages in an orchestration? Did these come from the same place that provided the wsdl URL? Or was it something you optionally had wsdl.exe dump out?

    - You connected what to a two-way port in the orchestration? A construct message of the appropriate type for the request (using the inbound message as the source)?

    I think part of my confusion is that it’s not clear why an orchestration is needed at all since the whole point is to wind up using a SOAP port assigned directly to a web service instead of to an orchestration.

    Any details you could add to clarify this would be great. Thanks,

    Donnie

  2. 2 Richard Seroter August 9, 2007 at 3:56 pm

    Good questions.

    Point #1. I used schemas provided by the same group that gave me the WSDL. If they built a WSDL, there’s most likely a schema either embedded or external.

    Point #2. I was unclear. I connected send and receive shapes (with the request and response message type) to a two-way port in the orchestration.

    You can definitely use a web service with no orchestration, but when you have request/response scenarios, often you need an orchestration to process the response. For one-way scenarios, you can use this mechanism to avoid orchestrations completely.

    Let me know if that helps.

  3. 3 Vishy August 15, 2007 at 8:46 am

    Hi

    Thanks for this trick. It saves a big hassle of rereferencing the stufff everytime its built.
    Although what happens if we’ve a map based on generated schema? How do we get these maps working?

    Thanks

    Vishy

  4. 4 Richard Seroter August 15, 2007 at 3:50 pm

    Hey Vishy,

    Map should be fine, assuming you have a schema for the downstream system. The map gets applied before the proxy class gets called, so assuming you are mapping TO the output format, everything’s cool.

    Is that what you were thinking?

  5. 5 Sérgio October 24, 2007 at 2:11 am

    Hey Richard,

    Great article!

    One question: did you tried this with complex types?

    Thanks

  6. 6 Richard Seroter October 24, 2007 at 6:44 am

    Hey Sérgio,

    The example above (and what I do in production solutions) actually is a complex type. Simple types might actually be a challenge, but this concept is ready-made for complex types.

  7. 7 savagerider December 31, 2007 at 10:28 pm

    Hi,

    Have you tried to consume web service that has only schema and method name given but no wsdl?

    Any clue on this ?

    Thanks.

  8. 8 Richard Seroter January 1, 2008 at 2:14 am

    Hey savagerider,

    So your “service” doesn’t really have a WSDL behind it? I’d probably just do an HTTP post to that URL then using the schema and endpoint.

  9. 9 Mike Foerster January 8, 2008 at 7:53 am

    Great article! I was fighting with this for a couple of days now!

    I have one problem, I have a complex document that i want to push into a single string that the other server will expand and use. Any good ideas to do this?

  10. 10 Richard Seroter January 10, 2008 at 7:30 am

    Hi Mike,

    I think you’ll have to do that via a custom pipeline component. Since you can’t map from a complex to simple type, the only solution I’m aware of is within a pipeline.

  11. 11 Hari January 18, 2008 at 4:49 am

    Hi
    I have the wsdl file for the webservice.
    Using this I have created a web proxy and added to biz talk project.
    When I drop the message for the web service request iam getting the parameter error.
    I dont have schema what kind of schema should use for Web service request.
    Any help will be appreciated.

    Thanks

  12. 12 Richard Seroter January 24, 2008 at 1:29 pm

    Hari,
    If your web operation input is a simple type (which it sounds like since you can’t find a schema under your web reference), then it’s a bit tricky to call your service without an orchestration. You’d have to use a custom pipeline to build the appropriate web message since you don’t have a schema to map to.

  13. 13 Hari February 12, 2008 at 11:36 pm

    Thanks for your reply.
    Iam using an orchestration.
    Is there a sample where custom pipeline is used for message creation.
    Iam assuming the message to be similar to the structure found in the wsdl file.

    Thanks

  14. 14 Edith February 19, 2008 at 8:28 am

    I’m using BizTalk 2004 and don’t see the web service tab. Do you know of a way to set the AssemblyName?

  15. 15 Richard Seroter February 19, 2008 at 11:24 am

    Hi Edith,

    Doing the “web services via messaging” was a new feature of BizTalk 2006. Don’t think it’s possible in 2004 …

  16. 16 Q April 1, 2008 at 11:03 pm

    How did you fix your proxy serialisation error? I am consuming a method that has no XSD and the only limited info I get is in the WSDL. Coudl you please add what your message looked like before and after fixing?

    Thanks
    Q

  17. 17 Richard Seroter April 3, 2008 at 6:28 am

    Q,
    If you’re referring to the last error mentioned, the “pre” message had an empty “date” node and empty “integer” node, neither of which was allowed. So, to fix it, I added default values. Look at your proxy class and observe the input parameter type and make sure that any dates or ints have non-null values.

  18. 18 Anjali August 1, 2008 at 9:48 am

    This is a very informative article. I have a similar issue, where I am trying to call a web service which accepts string as its only parameter. I too do not have any received message, so I want to construct message on my own in Expression shape in orchestration. The string is in fact XML. I am getting an error that “Failed to serialize the message part “MaterialXML” into the type “String” using namespace “. I greatly appreciate any suggestions you may have.

  19. 19 Richard Seroter August 4, 2008 at 11:35 pm

    If your service only takes a string, and you are calling from an orchestration, you will still need to construct the message using a “construct” shape. And, you’ll have a message type auto-generated by the web/service reference.

  20. 20 Pradeep August 7, 2008 at 10:34 pm

    Hi Richard

    I have published a Biztalk Orchestration as a WCF service. The orchestration takes in a message of type “System.String” and returns a message of type “System.String”. I have a test client(A windows application) where I added this service as a “Service Reference”. When I try calling the method from the object instantiated from the proxy class, I realised that the method takes in just one reference parameter of string type. But the service always returns null as the output value.
    All I do in the orchestration is assign some text to the string message before sending it out.
    Just to confirm if the message is being constructed properly, I tried writing this value to a file through a send port and I get my message intact there.

    When I published this orchestration as a web service (.asmx), it worked perfectly fine.

    Any help in resolving this will be greatly appreciated.

  21. 22 Richard Seroter August 11, 2008 at 6:44 am

    Hey Pradeep,

    I seem to recall while writing my recent article series on WCF that the WCF services didn’t work the same as ASMX services with regards to simple types (http://www.topxml.com/code/cod-491_10213_biztalk-and-wcf-part-v-publishing-operations-patterns.aspx).

    However, it doesn’t appear impossible, as simple types can be returned by the service. That said, I can’t know for sure why your scenario isn’t working, but you may want to consider switching to a complex type instead.


  1. 1 Tricks with Schemas Part 2: Referencing Schemas from Third Party WebServices « Connected Pawns Trackback on September 25, 2008 at 4:53 pm
  2. 2 Consuming Web Service without Web Reference | keyongtech Trackback on January 18, 2009 at 8:55 am

Leave a Reply




Disclaimer

Entries and comments here do not necessarily reflect the opinions, attitudes, and statements of my employer, my friends, or anyone associated with me.

Syndication

Publications

Order my new book SOA Patterns with BizTalk Server 2009 (Amazon.com, Packt Publishing)

Contact Me

Categories

Twitter Feed

Blog Stats

  • 181,696

 

April 2007
S M T W T F S
« Mar   May »
1234567
891011121314
15161718192021
22232425262728
2930