On-the-fly Translation using the Microsoft Translator Service

When writing an application that supports multiple languages, obtaining proper (read human) translations of the source material is paramount if you want to convey a professional image to your clients.  Automated translation has come a long way over the years, and will no doubt continue to improve, but is simply not a replacement for the traditional manual approach.

One of our employees is a native Italian, and finds the automated translation results of all the current providers very amusing – he laughs out loud – but he admits they do get the point across, so they are still a worthwhile addition to an application depending on what you are trying to achieve.

In Year View the bulk of the text shown is static, and thus can be properly translated.  However, the core objects in this application - namely the categories and appointments – are somewhat more dynamic: they are user entered/defined.  Thus we cannot perform a manual translation; automation to the rescue!

Personally I think that the ‘approximate’ translation we will obtain via an online service is something that should be made visually distinct to the end-user, so I intend to provide a button to toggle this service next to the list of languages that can be picked from.  This means that initially the user will get the proper static translation for the application, but can then request approximate translations for the categories and appointments.  This also means that the default performance is not impacted by extra data retrieval calls unless the end-user requests it, and they also have the control to ‘turn it off’ if the translations are less helpful than the original material.

Anyway, let’s have a look at how simple it is to add on-the-fly translation using the Microsoft Translator Service.

Microsoft Translator Service

As I need to translate collections of categories and appointments, the SOAP service is the most appealing for use from my Silverlight 4 application. 

In Visual Studio 2010, to add a reference to a SOAP web service, right-click on the project and add a service reference to http://api.microsofttranslator.com/V2/Soap.svc and specify a suitable namespace (I picked MicrosoftTranslatorService). This will generate the proxy code in a LanguageServiceClient class in the project.

Then obtain an AppID from http://www.bing.com/developers/appids.aspx.

Now we can write some code:

C#
public enum TranslationGroup
{
    Categories,
    Appointments
}

private void TestTranslation()
{
    LanguageServiceClient client = new LanguageServiceClient();            
    TranslateOptions options = new TranslateOptions();
    ObservableCollection<string> categoriesText = new ObservableCollection<string>(
        new string[] { "Category One", "Category Two", "Category Three" });
    ObservableCollection<string> appointmentsText = new ObservableCollection<string>(
            new string[] { "Subject One", "Subject Two", "Subject Three" });
    string sourceLocale = string.Empty;
    string targetLocale = "ja";
    int maxTranslations = 1;

    // Wireup our event handler to deal with the results
    client.GetTranslationsArrayCompleted +=
        new EventHandler<GetTranslationsArrayCompletedEventArgs>(
            Client_GetTranslationsArrayCompleted);

    // Make asynchronous call to translate our categories
    client.GetTranslationsArrayAsync(AppId, categoriesText, sourceLocale,
        targetLocale, maxTranslations, options, TranslationGroup.Categories);

    // Make asynchronous call to translate our appointments
    client.GetTranslationsArrayAsync(AppId, appointmentsText, sourceLocale,
        targetLocale, maxTranslations, options, TranslationGroup.Appointments);            
}

In the above example, we have two collections – one for categories and the other for appointments – and have chosen to have automatic source locale detection (i.e. providing an string.Empty for sourceLocale).  Japanese is specified as the target locale, and only 1 translation per item (which tends to be what is returned anyway even if you specify higher values) is required.

Then we wire up our event handler that gets executed when the asynchronous call returns, followed by two calls to GetTranslationsArrayAsync.  (The reason we have two distinct calls rather than one combined call is that we want to both call and respond to the results for categories and appointments independently; something that is maybe not clear in this example code but makes sense if you think about the bigger picture: getting categories once, and then stepping through years.)

The handler is equally simple:

C#
private void Client_GetTranslationsArrayCompleted(object sender,
    GetTranslationsArrayCompletedEventArgs e)
{
    if (e != null)
    {
        switch ((TranslationGroup)e.UserState)
        {
            case TranslationGroup.Appointments:
                Debug.WriteLine("Appointments");
                break;
            case TranslationGroup.Categories:
                Debug.WriteLine("Categories");
                break;
        }

        if (!e.Cancelled && e.Error == null && e.Result != null)
        {                                    
            foreach (var i in e.Result)
            {
                if (i != null && i.Translations.Any())
                {
                    TranslationMatch match = i.Translations[0];
                    Debug.WriteLine(match.TranslatedText);
                }
            }                    
        }
    }
}

When we run, the output window shows the result (very quickly btw when I’ve been running this!):

image

My Japanese is not too hot (read non-existent), but you can clearly see the issue with such automated translation in this simple example when looking at the appointment results.  I wondered if this was because I had not specified the source locale instead preferring to use the automatic detection, but being explicit did not help rectify this translation.

I’m also dubious about how good the automatic source language detection is: it seems to work well for English, but I suspect ‘less well’ for other languages, so specifying if possible would be best.

Overall adding such functionality is quick and easy for us developers, and hopefully further widens the scope for an applications use by providing approximate translations on dynamic data.

UPDATE 18/06/2010

I’ve just updated the online demos of Year View to show this in action (http://demos.planetsoftware.com.au/YearViewDemo2): pick a language other than English from the list, and then click the button next to it to obtain the appointment and category translations.

Also, for those that might not be aware: Tim Heuer is working on a Microsoft Translator client library for Silverlight that uses an HTTP based approach.

Print | posted on Monday, 14 June 2010 3:32 PM

Feedback

# re: On-the-fly Translation using the Microsoft Translator Service

left by Catalin at 4/09/2010 12:46 AM Gravatar
I think Google language API is better than Microsoft Translator Service. For example, I've made http://www.sms-translator.net using Google, it was easy and works like a dream... Microsoft is still focused on desktop applications, rather than website services.

# re: On-the-fly Translation using the Microsoft Translator Service

left by Testking 70-680 at 18/11/2011 5:47 PM Gravatar
One of our employees is a native Italian, and finds the automated cribs conseguenze of all the tides ISP very amusing – he laughs out loud – but he admits they do get the core across, so they are still a worthwhile supplements to an surrender depending on what you are trying to achieve.
Title  
Name
Email (never displayed)
Url
Comments   
Please add 6 and 8 and type the answer here: