Jan 26, 2013

Using Microsoft Translator With ASP.NET MVC 4 Web API

This article explains how to use the Microsoft Translator API to translate text that was input by the user. Microsoft Translation Service is an online service which has support for AJAX, HTTP or SOAP and Basic subscriptions, up to 2 million characters a month, are free. Google's free Translation API are deprecated So Microsoft Translator is a good alternative. In this sample, we will use AJAX API for English to Hindi translation.

First, You’ll need to sign up in the Windows Azure Marketplace, Subscribe to the Microsoft Translator API, register your app and get your credentials(Client ID and Client Secret) and keep a note of them. Check following step by step guide for this:

Signing up for Microsoft Translator and getting your credentials.

Basic Flow:

Here is the basic flow of the system:

flow-token-authentication

1. The client requests to asp.net web api for the access token.

2. Web API has "Client ID" and "Client Secret" for the app in the marketplace. So it posts them to obtain the access token.

Note: We don't want to disclose "Client ID" and "Client Secret", that's why It's done on server side.

3. The response for the token request contains the access token.

4. the access token is given to the client.

5. Now client can access Microsoft Translator API with access token and request for translation.

6. The response for translation request is the translated text and client can display the output.

Web API:

Create a ASP.NET MVC 4 Web API Project and in Default ValuesController, Get action provides the access token as follows:


 public class ValuesController : ApiController
    {
         // GET api/values
        public async Task<String> Get()
        {

            string clientID = ConfigurationManager.AppSettings["ClientID"].ToString();
            string clientSecret = ConfigurationManager.AppSettings["ClientSecret"].ToString();
            Uri translatorAccessURI = new Uri("https://datamarket.accesscontrol.windows.net/v2/OAuth2-13");

            // Create form parameters that we will send to data market.
            Dictionary<string, string> requestDetails = new Dictionary<string, string>
            {
                { "grant_type", "client_credentials" },
                { "client_id",   clientID},
                { "client_secret",  clientSecret },
                { "scope", "http://api.microsofttranslator.com" }
            };

            FormUrlEncodedContent requestContent = new FormUrlEncodedContent(requestDetails);
            
            // We use a HttpClient instance for Azure Marketplace request
            HttpClient client = new HttpClient();

            //send to data market
            HttpResponseMessage dataMarketResponse = await client.PostAsync(translatorAccessURI, requestContent);
            
            // If client authentication failed then we get a JSON response from Azure Market Place
            if (!dataMarketResponse.IsSuccessStatusCode)
            {
                JToken error = await dataMarketResponse.Content.ReadAsAsync<JToken>();
                string errorType = error.Value<string>("error");
                string errorDescription = error.Value<string>("error_description");
                throw new HttpRequestException(string.Format("Azure market place request failed: {0} {1}", errorType, errorDescription));
            }
            
            // Get the access token to attach to the original request from the response body
            JToken response = await dataMarketResponse.Content.ReadAsAsync<JToken>();
            return HttpUtility.UrlEncode(response.Value<string>("access_token"));
        }
}

ClientID and ClientSecret stored in Web.Config appsettings are passed in HTTP POST request to the token service to obtain the access token. The response is JSON-encoded and includes the access token.

Ajax Client:

For simplicity, we are taking same app to consume web api, In Default view, UI structure is as follows:


<div id="body">
<input type="text" id="txtMsg" value="" />
<input type="button" id="btnTranslate" onclick="translate();" value="Translate" /><br />
<span id="msg"></span>
</div>

UI has Textbox for user input, translate button and span to display output.


        var languageFrom = "en";
        var languageTo = "hi";

        function translate() {
            if ($('#txtMsg').val().trim().length == 0) {
                alert('Please enter text');
                return false;
            }
            
            $("#msg").text('loading...');

            $.ajax({
                type: "GET",
                url: 'api/values',
                contentType: "application/json; charset=utf-8",
                dataType: "json"
            }).done(function (token) {
                   var s = document.createElement("script");
                   s.src = "http://api.microsofttranslator.com/V2/Ajax.svc/Translate?oncomplete=mycallback&appId=Bearer " + token + "&from=" + languageFrom + "&to=" + languageTo + "&text=" + $('#txtMsg').val();
                   document.getElementsByTagName("head")[0].appendChild(s);
            }).fail(function (xhr, ajaxOptions, thrownError) {
                alert(xhr.responseText);
                $("#msg").text('Error');
            });
        }

        window.mycallback = function (response) {
            $("#msg").text('Translated Text: ' + response);
        }

In above code, when user clicks Translate button, Web API method is called to get access token which is added to a string, prefixed with "Bearer " (don’t forget the space) and send to the translator service. On translation service response, callback method is called to display the output. We are using "en"(English) to "hi"(Hindi) translation. You can find the other language codes here.

hindi-english-translation

Hope, You enjoy it.