using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text;
using System.Net;
using System.Net.Http;
using System.IO;
using Newtonsoft.Json;
namespace Azure_Demos
{
public partial class cognitive_text_translator : System.Web.UI.Page
{
const string TEXT_TRANSLATION_API_SUBSCRIPTION_KEY = "[your key]";
const string TEXT_ANALYTICS_API_SUBSCRIPTION_KEY = "[your key]";
const string BING_SPELL_CHECK_API_SUBSCRIPTION_KEY = "[your key]";
public static readonly string TEXT_TRANSLATION_API_ENDPOINT = "https://api.cognitive.microsofttranslator.com/{0}?api-version=3.0";
const string TEXT_ANALYTICS_API_ENDPOINT = "https://westus.api.cognitive.microsoft.com/text/analytics/v2.0";
const string BING_SPELL_CHECK_API_ENDPOINT = "https://api.cognitive.microsoft.com/bing/v7.0/spellcheck/";
private string[] languageCodes; // array of language codes
// Dictionary to map language code from friendly name (sorted case-insensitively on language name)
private SortedDictionary languageCodesAndTitles =
new SortedDictionary(Comparer.Create((a, b) => string.Compare(a, b, true)));
protected void Page_Load(object sender, EventArgs e)
{
// at least show an error dialog if there's an unexpected error
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(HandleExceptions);
if (!IsPostBack)
{
if (TEXT_TRANSLATION_API_SUBSCRIPTION_KEY.Length != 32
|| TEXT_ANALYTICS_API_SUBSCRIPTION_KEY.Length != 32
|| BING_SPELL_CHECK_API_SUBSCRIPTION_KEY.Length != 32)
{
Response.Write("One or more invalid API subscription keys.\n\n" +
"Put your keys in the *_API_SUBSCRIPTION_KEY variables in MainWindow.xaml.cs. Invalid Subscription Key(s)");
}
else
{
GetLanguagesForTranslate(); // get codes and friendly names of languages that can be translated
PopulateLanguageMenus(); // fill the drop-down language lists
}
}
}
// Global exception handler to display error message and exit
private static void HandleExceptions(object sender, UnhandledExceptionEventArgs args)
{
Exception e = (Exception)args.ExceptionObject;
HttpResponse httpResponse = new HttpResponse(TextWriter.Null);
httpResponse.Write(e.Message);
}
// ***** POPULATE LANGUAGE MENUS
private void PopulateLanguageMenus()
{
// Add option to automatically detect the source language
ddlLangFrom.Items.Add("Detect");
int count = languageCodesAndTitles.Count;
foreach (string menuItem in languageCodesAndTitles.Keys)
{
ddlLangFrom.Items.Add(menuItem);
ddlLangTo.Items.Add(menuItem);
}
// set default languages
ddlLangFrom.SelectedItem.Value = "Detect";
//ddlLangTo.SelectedItem.Value = "English";
}
// ***** DETECT LANGUAGE OF TEXT TO BE TRANSLATED
private string DetectLanguage(string text)
{
string uri = "https://api.cognitive.microsofttranslator.com/detect?api-version=3.0";
System.Object[] body = new System.Object[] { new { Text = txtToTranslate.Text } };
var requestBody = JsonConvert.SerializeObject(body);
// create request to Text Analytics API
using (var client = new HttpClient())
using (var request = new HttpRequestMessage())
{
// Set the method to POST
request.Method = HttpMethod.Post;
// Construct the full URI
request.RequestUri = new Uri(uri);
// Add the serialized JSON object to your request
request.Content = new StringContent(requestBody, Encoding.UTF8, "application/json");
// Add the authorization header
request.Headers.Add("Ocp-Apim-Subscription-Key", "[your key]");
// Send request, get response
var response = client.SendAsync(request).Result;
var jsonString = response.Content.ReadAsStringAsync().Result;
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
dynamic jsonResponse = serializer.DeserializeObject(jsonString);
// fish out the detected language code
var languageInfo = jsonResponse[0];
if (languageInfo["score"] > (decimal)0.5)
return languageInfo["language"];
else
return "";
}
}
// ***** CORRECT SPELLING OF TEXT TO BE TRANSLATED
private string CorrectSpelling(string text)
{
string uri = BING_SPELL_CHECK_API_ENDPOINT + "?mode=spell&mkt=en-US";
// create request to Bing Spell Check API
HttpWebRequest spellCheckWebRequest = (HttpWebRequest)WebRequest.Create(uri);
spellCheckWebRequest.Headers.Add("Ocp-Apim-Subscription-Key", BING_SPELL_CHECK_API_SUBSCRIPTION_KEY);
spellCheckWebRequest.Method = "POST";
spellCheckWebRequest.ContentType = "application/x-www-form-urlencoded"; // doesn't work without this
// create and send body of request
string body = "text=" + System.Web.HttpUtility.UrlEncode(text);
byte[] data = Encoding.UTF8.GetBytes(body);
spellCheckWebRequest.ContentLength = data.Length;
using (var requestStream = spellCheckWebRequest.GetRequestStream())
requestStream.Write(data, 0, data.Length);
HttpWebResponse response = (HttpWebResponse)spellCheckWebRequest.GetResponse();
// read and parse JSON response and get spelling corrections
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
var responseStream = response.GetResponseStream();
var jsonString = new StreamReader(responseStream, Encoding.GetEncoding("utf-8")).ReadToEnd();
dynamic jsonResponse = serializer.DeserializeObject(jsonString);
var flaggedTokens = jsonResponse["flaggedTokens"];
// construct sorted dictionary of corrections in reverse order in string (right to left)
// so that making a correction can't affect later indexes
var corrections = new SortedDictionary(Comparer.Create((a, b) => b.CompareTo(a)));
for (int i = 0; i < flaggedTokens.Length; i++)
{
var correction = flaggedTokens[i];
var suggestion = correction["suggestions"][0]; // consider only first suggestion
if (suggestion["score"] > (decimal)0.7) // take it only if highly confident
corrections[(int)correction["offset"]] = new string[] // dict key = offset
{ correction["token"], suggestion["suggestion"] }; // dict value = {error, correction}
}
// apply the corrections in order from right to left
foreach (int i in corrections.Keys)
{
var oldtext = corrections[i][0];
var newtext = corrections[i][1];
// apply capitalization from original text to correction - all caps or initial caps
if (text.Substring(i, oldtext.Length).All(char.IsUpper)) newtext = newtext.ToUpper();
else if (char.IsUpper(text[i])) newtext = newtext[0].ToString().ToUpper() + newtext.Substring(1);
text = text.Substring(0, i) + newtext + text.Substring(i + oldtext.Length);
}
return text;
}
// ***** GET TRANSLATABLE LANGUAGE CODES
private void GetLanguagesForTranslate()
{
// send request to get supported language codes
string uri = String.Format(TEXT_TRANSLATION_API_ENDPOINT, "languages") + "&scope=translation";
WebRequest WebRequest = WebRequest.Create(uri);
WebRequest.Headers.Add("Ocp-Apim-Subscription-Key", TEXT_TRANSLATION_API_SUBSCRIPTION_KEY);
WebRequest.Headers.Add("Accept-Language", "en");
WebResponse response = null;
// read and parse the JSON response
response = WebRequest.GetResponse();
using (var reader = new StreamReader(response.GetResponseStream(), UnicodeEncoding.UTF8))
{
var result = JsonConvert.DeserializeObject>>>(reader.ReadToEnd());
var languages = result["translation"];
languageCodes = languages.Keys.ToArray();
foreach (var kv in languages)
{
languageCodesAndTitles.Add(kv.Value["name"], kv.Key);
}
}
}
// ***** PERFORM TRANSLATION ON BUTTON CLICK
private async void Translate()
{
string textToTranslate = txtToTranslate.Text.Trim();
string fromLanguage = ddlLangFrom.SelectedValue.ToString();
string fromLanguageCode;
GetLanguagesForTranslate();
// auto-detect source language if requested
if (fromLanguage == "Detect")
{
fromLanguageCode = DetectLanguage(textToTranslate);
if (!languageCodes.Contains(fromLanguageCode))
{
Response.Write("The source language could not be detected automatically " +
"or is not supported for translation. Language detection failed");
return;
}
}
else
fromLanguageCode = languageCodesAndTitles[fromLanguage];
string toLanguageCode = languageCodesAndTitles[ddlLangTo.SelectedValue.ToString()];
// spell-check the source text if the source language is English
if (fromLanguageCode == "en")
{
if (textToTranslate.StartsWith("-")) // don't spell check in this case
textToTranslate = textToTranslate.Substring(1);
else
{
textToTranslate = CorrectSpelling(textToTranslate);
txtToTranslate.Text = textToTranslate; // put corrected text into input field
}
}
// handle null operations: no text or same source/target languages
if (textToTranslate == "" || fromLanguageCode == toLanguageCode)
{
lblTranslateResult.Text = textToTranslate;
return;
}
// send HTTP request to perform the translation
string endpoint = string.Format(TEXT_TRANSLATION_API_ENDPOINT, "translate");
string uri = string.Format(endpoint + "&from={0}&to={1}", fromLanguageCode, toLanguageCode);
System.Object[] body = new System.Object[] { new { Text = textToTranslate } };
var requestBody = JsonConvert.SerializeObject(body);
using (var client = new HttpClient())
using (var request = new HttpRequestMessage())
{
request.Method = HttpMethod.Post;
request.RequestUri = new Uri(uri);
request.Content = new StringContent(requestBody, Encoding.UTF8, "application/json");
request.Headers.Add("Ocp-Apim-Subscription-Key", TEXT_TRANSLATION_API_SUBSCRIPTION_KEY);
request.Headers.Add("X-ClientTraceId", Guid.NewGuid().ToString());
var response = await client.SendAsync(request);
var responseBody = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<List<Dictionary<string, List<Dictionary<string, string>>>>>(responseBody);
var translations = result[0]["translations"];
var translation = translations[0]["text"];
// Update the translation field
lblTranslateResult.Text = translation;
}
}
protected void btnTranslate_Click(object sender, EventArgs e)
{
Translate();
}
protected void btnClear_Click(object sender, EventArgs e)
{
txtToTranslate.Text = string.Empty;
lblTranslateResult.Text = string.Empty;
}
}
}