Continuing from my last post, I’ve completed a deep-dive walkthrough on how to create and deploy an assembly that will help you perform “dynamic-text-translation” from X++ code (link at the bottom of this article).
 
The walkthrough requires you to be familiar with creating a .Net assembly in C# code. The code is posted here for reference:
 
TranslateUtilities
 
using System;
using System.Linq;
using System.Net;
using Microsoft;
 
namespace TranslateUtilities
{
    public class TranslateClass
    {
        /// <summary>
        /// Invoke the Windows Azure Marketplace Bing Translator.
        /// </summary>
        /// <returns>The dynamically translated phrase</returns>
        public string TranslatePhraseUsingBing(string _phrase, string _sourceLanguage, string _targetLanguage)
        {
            // Call a InitializeTranslatorContainer to get a TranslatorContainer
            TranslatorContainer tc = InitializeTranslatorContainer();
 
            // Source language object
            DetectedLanguage objSourceLanguage = new DetectedLanguage();
            try
            {
                objSourceLanguage.Code = _sourceLanguage.Substring(0, 2);
            }
            catch (System.Exception ex)
            {
                objSourceLanguage.Code = "";
            }
 
            // Target language object
            Language objTargetLanguage = new Language();
            try
            {
                objTargetLanguage.Code = _targetLanguage.Substring(0, 2);
            }
            catch (System.Exception ex)
            {
                objTargetLanguage.Code = "";
            }
 
            // Attempt the translation
            try
            {
                if (objSourceLanguage.Code == "")
                {
                    objSourceLanguage = DetectSourceLanguage(tc, _phrase);
                }
                Translation objTranslation = new Translation();
                objTranslation = TranslateString(tc, _phrase, objSourceLanguage, objTargetLanguage);
 
                // Handle the error condition
                if (objTranslation == null)
                {
                    return ("Translation failed.");
                }
                else
                {
                    return (objTranslation.Text);
                }
            }
            catch (System.Exception ex)
            {
                return ex.Message;
            }
        }
 
        /// <summary>
        /// Creates an instance of a TranslatorContainer that calls the public production MicrosoftTranslator service.
        /// </summary>
        /// <returns>The generated TranslatorContainer</returns>
        private static TranslatorContainer InitializeTranslatorContainer()
        {
            // this is the service root uri for the Microsoft Translator service 
            var serviceRootUri = new Uri("https://api.datamarket.azure.com/Bing/MicrosoftTranslator/");
 
            // this is the Account Key for this app
            var accountKey = "**************************************************";
 
            // the TranslatorContainer gives us access to the Microsoft Translator services
            var tc = new TranslatorContainer(serviceRootUri);
 
            // Give the TranslatorContainer access to your subscription
            tc.Credentials = new NetworkCredential(accountKey, accountKey);
            return tc;
        }
 
        /// <summary>
        /// Uses the TranslatorContainer to identify the Language in which inputString was written.
        /// </summary>
        /// <param name="tc">The TranslatorContainer to use</param>
        /// <param name="inputString">The string to identify</param>
        /// <returns>The Language Code for a language that this string could represent, or null if one is not found.</returns>
        private static DetectedLanguage DetectSourceLanguage(TranslatorContainer tc, string inputString)
        {
            // Calling Detect gives us a DataServiceQuery which we can use to call the service
            var translateQuery = tc.Detect(inputString);
 
            // Retrieve a list of potential languages that the detecion has discovered
            var detectedLanguages = translateQuery.Execute().ToList();
 
            // Only continue if the Microsoft Translator identified the source language if there are multiple, let's go with the first.
            if (detectedLanguages.Count() > 0)
            {
                return detectedLanguages.First();
            }
            else
            {
                return null;
            }
        }
 
        /// <summary>
        /// Uses the TranslatorContainer to translate inputString from sourceLanguage to targetLanguage.
        /// </summary>
        /// <param name="tc">The TranslatorContainer to use</param>
        /// <param name="inputString">The string to translate</param>
        /// <param name="sourceLanguage">The Language Code to use in interpreting the input string.</param>
        /// <param name="targetLanguage">The Language Code to translate the input string to.</param>
        /// <returns>The translated string, or null if no translation results were found.</returns>
        private static Translation TranslateString(TranslatorContainer tc, string inputString, DetectedLanguage sourceLanguage, Language targetLanguage)
        {
            // Generate the query
            var translationQuery = tc.Translate(inputString, targetLanguage.Code, sourceLanguage.Code);
 
            // Call the query and get the results as a List
            var translationResults = translationQuery.Execute().ToList();
 
            // Verify there was a result
            if (translationResults.Count() <= 0)
            {
                return null;
            }
 
            // In case there were multiple results, pick the first one
            var translationResult = translationResults.First();
 
            return translationResult;
        }
    }
}
 
 
In the above code, make sure you replace the “accountKey” variable in the “InitializeTranslatorContainer” method with your account key that can be found on your windows azure data market account page: [https://datamarket.azure.com/account]
 
Once the assembly is deployed to the AOT, setup a simple X++ job to test the functionality:
 
static void TestTranslate(Args _args)
{
    TranslateUtilities.TranslateClass objTranslate = new TranslateUtilities.TranslateClass();
 
    str sourcePhrase, targetPhrase;
 
    sourcePhrase = "The weather is absolutely shocking today";
 
    targetPhrase = objTranslate.TranslatePhraseUsingBing(sourcePhrase, "", "de");
 
    info(targetPhrase);
 
}
 
 
The above sample code should perform an English > German translation (“en” > “de”). If you supply sufficient text in the “source phrase” then you don’t need to specify the source language code because the Microsoft Translator should be able to make a good determination by itself. This feature is very useful if your application captures phrases that have been entered from a wide variety of language operators… or if you are importing data from indiscriminate multi-linguage sources.
 

·         The full list of (currently available languages can be found here : [http://msdn.microsoft.com/en-us/library/hh456380.aspx]

 
The performance of the API cannot be guaranteed as its dependant on network throughput and the load on the Microsoft Azures servers, so I suggest caching background translations in the database for performance sensitive tasks.
 
Have fun…