By sam
August 11, 2010 at 2:12 PM

Recently I was in Redmond for the BizTalk VTS Summit, with a bunch of colleague BizTalk experts from all over the world.  During one of the discussions we had, a question came up about the fact that it seemed that to host HTTP endpoints, it is required to have IIS as the real host configured.

After my suggestion that is was perfectly possible to bypass IIS in this process, it looked that quite a number of attendees didn’t know about this.  And that’s the reason why I decided to add it to our blog…

WCF-Custom vs WCF-CustomIsolated

First of all, I think it is a best practice to avoid using the non-WCF-custom adapters (like WCF-WSHttp, etc).  I always suggest colleagues and customers to use the WCF-Custom or WCF-CustomIsolated adapter, since they are the only adapters that provide the maximum capabilities of WCF in BizTalk.  The other WCF-* adapters only provide a subset of the various binding and behavior settings, specific for their binding, which results in an adapter change, when a more advanced setting is needed one day.

The WCF-Custom adapter, is the adapter that is used to host WCF endpoints inside BizTalk.  The WCF-Isolated adapter is hosted in a BizTalk Isolated Host, which is typically IIS.

The BizTalk WCF Service Publishing wizard

To expose an orchestration or a schema as a WCF service in BizTalk, the BizTalk WCF Service Publishing wizard is the typical way to use.  In this wizard, the orchestration or schema needs to be selected and a choice between three adapters is possible: WCF-BasicHttp, WCF-WSHttp, WCF-CustomIsolated. 

The last step of the wizard is used to create a web directory in IIS, where the BizTalk svc file will be created that hosts the custom WCF Service Host that will link through to the BizTalk Receive location. 

WCF Service type WCF Service Location

Unfortunately, the WCF Publishing wizard does not allow to select the ‘In-Process’ adapters.  All of the three adapters/bindings are only available through an isolated host and required IIS.

Hosting the endpoint in the BizTalk process

To host the endpoint inside the BizTalk process, we need to manually create the WCF receive location.  To do so, we just need to select the WCF-Custom adapter and use the desired binding: BasicHttpBinding or WsHttpBinding. 

The following steps need to be used for this:

  1. Create a new receive location with the desired name
  2. Select the WCF-Custom adapter and open the properties for this adapter
  3. Specify an address for the endpoint (picture 1) Take into account that when IIS is already running on the machine, you might need to specify a different available port.
  4. Select your binding (or use the customBinding for full flexibility) in the Binding tab page. (picture 2) and set all desired binding properties to their correct setting.
  5. In the Messages tab page, you can also specify that failed request messages need to be suspended and that exceptions should be returned to the consumer. (picture 3)

wcf1 wcf2 wcf3

Metadata publication

One downside of this way of work is the metadata publishing.  If you would query the exposed endpoint for the WSDL, you would get to see the WSDL of the generic BizTalk WCF Service Host with the 5 operations.

Therefore, it is needed to publish the metadata endpoint to IIS and provide that endpoint to the consumers of your in-process service.  But this way of work, is similar to the other protocols (like netMsmq, netTcp…)

Advantages

  • Consistent approach for all binding types, independent of protocol.
  • No extra configuration / deployment needed (specific IIS security on IIS application pools, etc)
  • Performance (no extra hop)

Sam Vanhoutte, CODit

Posted in: BizTalk | WCF

Tags: , ,


August 6, 2010 at 8:09 AM

The Bing API allows you to get results from multiple sourcetypes, one of them being the Translation SourceType.

More Info on the API can be found here.

The SDK comes with some nice samples and can be found here.

As a practise we are going to do a query from a BizTalk Pipeline component  to translate a field configured by an XPath.

In design we need to define a source language, destination language and the XPath to the field we will translate.

TranslationLanguage is just an enum to facilitate configuration in pipeline design time.

 

private Helper.TranslationLanguage _SourceLang;
private Helper.TranslationLanguage _DestLang;
private string _XPath; 

public Helper.TranslationLanguage SourceLanguage
{ get; set; } 

public Helper.TranslationLanguage DestinationLanguage
{ get; set; } 

public string XPath
{ get; set; }

Next we modify the Execute function of the component to call the Tranlate method we will define further on, to modify the message.

A good way to do this is by using the XPathMutatorStream. More info on XPathMutatorStream can be found here.

 

IBaseMessage Microsoft.BizTalk.Component.Interop.IComponent
Execute(IPipelineContext pContext, IBaseMessage pInMsg)
{
          IBaseMessage biztalkMessage = pInMsg;
          XmlReader reader = XmlReader.Create(pInMsg.BodyPart.Data);
          XPathCollection xpaths = new XPathCollection();
          xpaths.Add(this._XPath);
          ValueMutator mutator = new ValueMutator(handleXpathFound);
          pInMsg.BodyPart.Data = new XPathMutatorStream(reader, xpaths, mutator);
          return pInMsg;
} 

private void handleXpathFound(int matchIdx, Microsoft.BizTalk.XPath.XPathExpression matchExpr, string origVal, refstring finalVal)
{
          finalVal = Helper.Translate(SourceLanguage, DestinationLanguage, origVal);
}

 

Finally we’ll send a request to the Bing API using the XML protocols ( we are BizTalk Developpers after all … ).

We build the query using the arguments provided and return the translation:

 

public static string Translate(TranslationLanguage SourceLang,  TranslationLanguage DestLang, string text)
{
          LoadLanguages();
          HttpWebRequest request = BuildRequest(_Languages[SourceLang], _Languages[DestLang], text);
          try
          {
                    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                    XmlDocument document = new XmlDocument();
                    document.Load(response.GetResponseStream());

                    XmlNamespaceManager nsmgr = new XmlNamespaceManager(document.NameTable);
                    nsmgr.AddNamespace("tra", "http://schemas.microsoft.com/LiveSearch/2008/04/XML/translation");

                    return document.DocumentElement.SelectSingleNode("./tra:Translation/tra:Results/tra:TranslationResult", nsmgr).InnerText;
          }
          catch (WebException ex)
          {
                    throw new ApplicationException("Web Error while translating",ex);
          }
}

static HttpWebRequest BuildRequest(string SourceLang, string DestLang, string text)
{
          string requestString = "http://api.bing.net/xml.aspx?"
          + "AppId=" + AppId
          + "&Query=" + text
          + "&Sources=Translation"
          + "&Version=2.2"
          + "&Translation.SourceLanguage=" + SourceLang
          + "&Translation.TargetLanguage=" + DestLang;

          HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(        requestString);

          return request;
}

 

Time to test: Create a BizTalk project with

A schema for testing:

 

A pipeline with our new component. We define the xpath to the Value Record, the source and destinationlanguage. I created pipelines to translate to Dutch and French from English:

 

Deploy in BiZtalk, create Receiveport with Receivelocation, 2 Sendports with a filter on the Receiveportname and our pipeline to translate to French and Dutch.

 

Drop a test message:


<ns0:TestTranslatorSchema 

xmlns:ns0="http://TestTranslator.TestTranslatorSchema">

  <Value>What language is this written in?</Value>

</ns0:TestTranslatorSchema>

 

And observe the results:

 

<ns0:TestTranslatorSchema 

xmlns:ns0="http://TestTranslator.TestTranslatorSchema">

  <Value>Quelle langue c'est écrit ?</Value>

</ns0:TestTranslatorSchema>

 

<ns0:TestTranslatorSchema 

xmlns:ns0="http://TestTranslator.TestTranslatorSchema">

  <Value>In welke taal is dit geschreven?</Value>

</ns0:TestTranslatorSchema>

 


Korneel Vanhie, CODit


Posted in: BizTalk

Tags:


August 3, 2010 at 9:43 AM

BizTalk can be installed using command line such as this:

"Setup.exe /quiet /addlocal all /IGNOREDEPENDENCIES /INSTALLDIR D:\program files\Microsoft BizTalk Server 2010 /s D:\Install\biztalk2010/configBiztalk2010.xml"

But we had an issue with the INSTALLDIR flag. Using the above path, the installation was failing with an error "Unable to load xml file: c:\users\insUser\AppData\Local\Temp\EBZ39051.tmp\1033\Autorun.xml"

After quite a lot of investigation the developer realised that the INSTALLDIR path with spaces in the name was the culprit. Using quotes around the path did not work either. Instead, the path should be its DOS short name. In order to do that, do the following:

1) Create the destination folder using the commande MKDIR on the destination drive
2) Get the DOS path using the command DIR /X from the destination drive
3) Run again using now the command such as in this example using the new path: "Setup.exe /quiet /addlocal all /IGNOREDEPENDENCIES /INSTALLDIR D:\PROGRA~2\MICROS~2\ /s D:\Install\biztalk2010/configBiztalk2010.xml". It should work fine!

Vincent ROUET, CODit