BizTalk In-Process Hosting Of WCF Http Services

After my post of various WCF scenarios, I received a couple questions about using the in-process host to receive WCF HTTP requests, so I thought I’d briefly show my configuration setup for making this work.

First off, I had created a “regular” IIS-hosted WCF web service and auto-generated a receive port and location. I decided to reuse that receive port, and created a new receive location for my in-process HTTP receive. I used the WCF-Custom adapter, which as you can see, runs only within an in-process host.

The first adapter configuration tab is where you identify the endpoint URL. This value is completely made-up. I chose an unused port (8910), and then created my desired URL.

Next, on the Binding tab, I set the wsHttpBinding as the desired type.

Next, I added a behavior for “serviceMetadata” to allow for easy discovery of my service contract.

That’s it for the receive location configuration. I need to enable the receive location in order to instantiate the WCF service host. If I try to browse to my service URL while the location is disabled, I get a “page cannot be displayed” error. Once I enable the location, and hit my made-up URL in the browser, I can see the service description. Note that if I had not created the serviceMetadata behavior, I would have received a “Metadata publishing for this service is currently disabled.” message when viewing my service in the browser.

So, now I can generate the necessary client-side objects and configuration to call this service. My client application’s configuration file has the following endpoint entry:

<endpoint 
   address="http://localhost:8910/incidentreporting/incident.svc"
   binding="wsHttpBinding" 
   bindingConfiguration="WSHttpBinding_ITwoWayAsyncVoid"
   contract="Service1" name="IncidentInProcSvc">
   <identity>
       <userPrincipalName value="myserver\user123" />
   </identity>
</endpoint>

You’ll notice my endpoint address matches the value in the receive location, and an “identity” node exists because my service configuration (in the receive location) identified clientCredentialType as “Windows” for message/transport security.

There you go. Pretty easy to “build” a service that is hosted within the BizTalk process, completely bypassing IIS, and leave the service consumer none the wiser.

UPDATE: You may notice that nowhere above did I build a contract into the service itself. I reused a contract in my client endpoint, but how would the service consumer know what to send to my service? This is probably where you’d decide to create a MEX endpoint. You’d point at the WS-Custom receive location in the WCF Publishing Wizard, and choose a schema(s) to represent the contract. Then users would point to the MEX service to generate their strongly-typed client components.

Technorati Tags: ,

Author: Richard Seroter

Richard Seroter is currently the Chief Evangelist at Google Cloud and leads the Developer Relations program. He’s also an instructor at Pluralsight, a frequent public speaker, the author of multiple books on software design and development, and a former InfoQ.com editor plus former 12-time Microsoft MVP for cloud. As Chief Evangelist at Google Cloud, Richard leads the team of developer advocates, developer engineers, outbound product managers, and technical writers who ensure that people find, use, and enjoy Google Cloud. Richard maintains a regularly updated blog on topics of architecture and solution design and can be found on Twitter as @rseroter.

34 thoughts

  1. Would you generally say that it’s ok having your services hosted by BizTalk and not by IIS (let’s say we have IIS 7 and are able to host WCF services as well)?

    To me it feels like one looses so much functionality like recycling, tracing and all the features that makes IIS a great service host.

    I’d be interesting to hear your thought on that.

    Richard Hallgren

  2. I’m interested in seeing if messages that don’t validate against the schema will be suspended in BizTalk or if this approach will have the same IIS behavior of just swallowing things without any real notification to the BT admin. If this improves, it might just be enough to outweigh Hallgren’s argument for using IIS. Let me know if this is something you tested…

  3. I just ran a quick test, and if I do a simple HTTP post to the WCF Receive Location, and pass invalid XML, a message DOES appear in the event log. So, hosting the HTTP in-process does afford me the luxury of actually knowing that a bad request came in.

    I doubt this will lead to a massive departure from using IIS as a service host, as it offers many benefits. But, I could argue it’s easier to manage the endpoints when they are contained in the BizTalk process, vs. having to bounce not only BizTalk hosts, but IIS as well.

  4. Creating passthrough wcf receive locations, using the wcf-custom adapter with the wshttp binding, leaves me with a method requiring an input System.ServiceModel.Channels.Message parameter. Since this type is abstract, what should I use instead?
    Thanks
    //Mikael

  5. Not sure if you saw the “update” to the post, but you’d want to create a MEX endpoint which gave your consumers a strong input contract, while still really accepting a “message” underneath.

  6. Richard,

    I have been beating my head against a wall for the last two weeks trying to get this to work. I have a receive location setup using wsHttpBinding. I get my message into BizTalk but my VB.NET client code ends up throwing the following error message:

    The request channel timed out while waiting for a reply after 00:00:59.9843497. Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding. The time allotted to this operation may have been a portion of a longer timeout.

    I have tried everything I could think about but nothing works. I can’t get this timeout to go away. Any idea?

    Thanks!

  7. Richard,

    Thanks for the quick response.

    I am not sure if this is a one way service. I set the service up following the steps you outlined in this article. It was my understanding that unless I was using msmq all services were request reply. I am pretty new to BizTalk so I may not be understanding that correctly.

    I don’t have an orchestration set up. I have a send port setup with a filter for my receive port that is dumping the message out to a file.

    Thanks again for the help. I really appreciate it.

  8. You can look at the WSDL and see if your web service is request only or request reply. If it’s request only, a silent acknowledgement still does come back. But, if you have a request/response service, and a receive location that is one way, not sure if that’s what is causing your timeout. And if you have a request/response receive port/location, you’ll need to return a valid response message. This is where something like orchestration usually comes in.

    How did you build the web service? Using the WCF Wizard in Visual Studio and choosing “build service from schemas”?

  9. Richard,

    I did not actually create a service ahead of time. I simply went into BizTalk and configured a ReceiveLocation. It was my understanding that I didn’t actually need to create a standalone WCF service if I am hosting it directly in BizTalk. Is that an ivalid understanding of how things work?

    If I point visual studio at that service and generate the WSDL it appears to me to be a request reply. There is a reply action on the BizTalkSubmit operation.

    If I do have to respond via the orchestration is there a good example out there of how to put that together?

    Thanks again!

  10. Richard,

    I am happy to report that I finally got things working correctly. I did indeed have a request reply setup but since I wasn’t returning a reply it was bombing out. Once I modified that it worked like a champ.

    I would not have stumbled upon this had it not been for your questions getting me to look at that a bit deeper. Thanks so much for taking the time to respond to my question. I really appreciate it.

    If you are ever in Omaha let me know. I definitely owe you a beer.

    Thanks again and I can’t wait for your next article!

    Dan

  11. Hello

    I tried do publish with the WFC-Custom Adapter in BizTalk 2006 R2 as described here. When I try to send in my test client an Xml-Message I always get http 400 Bad Request.

    If a send a wrong message (message type) a get another error and in the event log on the biztalk machine is an error!

    What do I do wrong?

    Thanks.

  12. I had a look a your article.
    Must the receive port be a request response port, if i try to publish a webservice in-proccess?

  13. Hi Harry. I wouldn’t think that the port needs to be request reqponse. But as you saw from my article, it’s fairly tricky to get all the metadata you need if you only expose a WCF service via in-process HTTP. How are you getting the “type” to submit to the service, and how are you actually calling the endpoint without a proxy class? Just doing an HTTP post to the URL?

  14. If a add the web reference in my vs project, the webservice method accepts the type XmlElement[] so I tried this, because I wanted just send an xmlmessage to the biztalk orchestration and biztalk should validate if the message is valide. But I always get an “Bad Request” error. (Perhaps my thougths are not right. I havn’t done so much with webservices.)

    XmlDocument doc = new XmlDocument();
    doc.Load(@”C:\Projects\IBS.OemPortal\LixtoAutomotive.xml”);
    XmlElement[] element = new XmlElement[1];
    element[0] = doc.DocumentElement;

    ibsmulti05.BizTalkServiceInstance ws = new BtsWcfClient.ibsmulti05.BizTalkServiceInstance();
    ws.BizTalkSubmit(element);

  15. For self hosting i followed this article but Biztalk submit method is failing and is throwing below error.
    The adapter “WCF-Custom” raised an error message. Details “System.NotSupportedException: Specified method is not supported.
    at Microsoft.BizTalk.Adapter.Wcf.Runtime.BizTalkServiceInstance.Microsoft.BizTalk.Adapter.Wcf.Runtime.ITwoWayAsync.BizTalkSubmit(Message message)

    Pls have a look at steps below and let me know if am wrong.

    1.Orchestation with reqresp port has been deployed.
    2.WCF published wizard has been used to generate normal iis wcf service by choosing ws-http binding and by checking receive port creation.
    3.Created manual receivelocation under receive port that was created by wizard and disabled auto generated receive location.
    4.New receive location is using wcf-custom adapter, binding is wshttpbinding and Service metadata behaviour is enabled for HTTPGet.
    5.Service proxy and config file were generated using vcutil utitlity.At this point i don’t have data contract to pass BizTalk submit method.
    6.To generate data contract, i ran wcf wizard to get MEX endpoint metadata for ws-http receive location(not ws-custom receive loc) that was created by the wizard in the step 2.It created data contract for calling.
    7.Using service proxy and data contract created in the above i tried to execute BizTalk submit method
    8.I was using service configuration file by renaming it to app.config.

    Ran the appln to test it and is generating above error mentioned.

  16. Jay,

    Can’t call the BizTalkSubmit operation. If you defined a specific MEX endpoint (or put a custom WSDL on the receive location), then you would execute that particular function.

    1. Richard,

      How do I publish the mex end point? or add a custom wsdl? I have walked through the article several times and I still cannot connect (configure the) the mex end point to the biztalk hosted wcf port.

      this approach is exactly what I want to do, but I cannot connect the dots to get a strongly typed port configured.

      Thank You,

      Will Weaver

      1. Richard, I’m trying to sound like an idiot here, I can create a mex end point in IIS and I can create the in-process receive location in BizTalk, I just cannot configure the two together. Am I supposed to modify and import the web.config into the receive port to get the mex endpoint definition for the receive locations wcf service?

        Thank You,

        Will Weaver

      2. Hi Will,

        I don’t have my environment up at the moment, but if you hand write a WSDL, you can put it into a web directory and reference in the “externalMetadataLocation” property in the ServiceMetadata behavior.

  17. Richard,

    I have a orchestration that accepts any xml (untyped message )using type XLANG.BaseTypes.dll. Any xml can come to this orchestration and using XPATH, I populate a message that goes to SQL DB and gets values from there. This orchestration then returns a reponse that is also of ANY type (XLANG.BaseTypes.dll). I exposed the orchestration as WCF and created a client to test this WCF. I am able to send a generic XMLDocument type message but return is always NULL. I tried by making WCF return type as string but it still did not work. I can validate the request and return in fiddler and they look good. I do not understand why then I can’t get the return value in my client application. Expected return value is “(s:Envelope xmlns:s=”http://schemas.xmlsoap.org/soap/envelope/”)(s:Body)(Return)1(/Return)(/s:Body)(/s:Envelope)” (pasted from fiddler).

    Below is the client code:

    ValidateSer.Client cl = new ValidateSer.Client();
    XmlDocument doc = new XmlDocument();
    XmlElement ele;
    doc.Load(@”C:\Projects\Validate.xml”);
    ele = doc.DocumentElement;
    cl.Operation_1(ref ele);
    cl.Close();

    Thanks in advance!

  18. Hi Richard,

    if I don’t want to use IIS at all and instead use the proxy class you mentioned in your article in top xml…How do I configure the proxy class and where do I put it to have a complete self-hosted service (no IIS)?

    Thank You,

    Will Weaver

    1. Hey Will,

      For the proxy class mentioned above (if I recall correctly), it was based off of a WSDL that I had previously had created. So, the svcutil.exe could be run against it and a valid proxy class generated. In that case, this is all the caller needs for generating the payload and you just need to make sure they are pointing at your BizTalk hosted endpoint. No IIS necessary if you hand people a WSDL or proxy class.

  19. Hi Richard, I’m using the WCF-BasicHTTP adapter and it seems like it has a default timout limit of 5 mins. everytime the response from the WS takes longer than 5 minutes I get the following error: System.TimeoutException: The HTTP request to…. has exceeded the allotted timeout of 00:05:00. The time allotted to this operation may have been a portion of a longer timeout. Can you tell me how his fedault limit can be increased???

  20. Hi Richard, I created an In-Process WCF receive location with the WCF-Custom adapter within BizTalk, and are struggling calling it from my c# code in my client application.

    I have create proxy classes of the schemas, and populated them, then created a message that I want to send,but cannot figure out how to send it to this service.(BizTalkSubmit always throws an error)

    Here is my code below, any advice would be appreciated…

    WCFCustomService.TwoWayAsyncClient client = new WCFCustomService.TwoWayAsyncClient(); //WCFCustomService–> what I called my service, when consuming it
    Request req = new Request();
    req.ConversationType = “xxx”
    System.ServiceModel.Channels.Message reqMsg = System.ServiceModel.Channels.Message.CreateMessage(MessageVersion.Soap11, “BizTalkSubmit”, req);
    System.ServiceModel.Channels.Message resp1 = client.BizTalkSubmit(reqMsg);
    // Use the ‘client’ variable to call operations on the service.
    MessageBox.Show(resp1.ToString());

    // Always close the client.
    client.Close();

    can I use it like this? or how would I call this service , using proxy classes…?

    Any help/advice would be appreciated…

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.