Archive Browser
Download AzureTranslationDemoV3.zip, last updated 11/04/2019 (45.48 KB)
Download- md5: 71243a5a58a5b2055e7ffbc8a12dbbbb
- sha1: b3ea3e69c98e9179121e56912434d6ffa37ed7e9
- sha256: 5a4c764a08816a7bfc3060ba0006883bf49134838680b88901018ef707a23650
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security;
using System.Text;
using PetaJson;
// Migrating from Azure translation API version 2 to 3
// http://www.cyotek.com/blog/migrating-from-azure-translation-api-version-2-to-3
// Translating text with Azure cognitive services
// http://www.cyotek.com/blog/translating-text-with-azure-cognitive-services
// This work is licensed under the Creative Commons Attribution 4.0 International License.
// To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/.
// Found this example useful?
// https://www.paypal.me/cyotek
namespace Cyotek.Demo.AzureTranslation
{
public sealed partial class TranslationClient
{
#region Constants
private const string _apiBaseUri = "https://api.cognitive.microsofttranslator.com/";
private const string _apiVersion = "3.0";
private const string _apiVersionQueryName = "api-version";
private const string _getLanguageNamesUri = _apiBaseUri + "languages";
private const string _getLanguagesForTranslateQuery = "scope=translation";
private const string _getLanguagesForTranslateUri = _apiBaseUri + "languages";
private const string _issueTokenUri = "https://api.cognitive.microsoft.com/sts/v1.0/issueToken";
private const int _minutesUntilTokenExpires = 8;
private const string _queryPrefix = "?" + _apiVersionQueryName + "=" + _apiVersion;
private const string _translateUri = _apiBaseUri + "translate";
#endregion
#region Fields
private string _authorizationKey;
private string _authorizationToken;
private DateTime _timestampWhenTokenExpires;
#endregion
#region Constructors
public TranslationClient()
{
_timestampWhenTokenExpires = DateTime.MinValue;
}
public TranslationClient(string authorizationKey)
: this()
{
_authorizationKey = authorizationKey;
}
#endregion
#region Properties
public string AuthorizationKey
{
get { return _authorizationKey; }
set
{
if (!string.Equals(_authorizationKey, value))
{
_authorizationKey = value;
_timestampWhenTokenExpires = DateTime.MinValue;
}
}
}
#endregion
#region Methods
public string[] GetLanguages()
{
string[] results;
// https://docs.microsoft.com/en-us/azure/cognitive-services/translator/reference/v3-0-languages?tabs=curl
results = null;
this.CheckToken();
this.ExecuteRequest(_getLanguagesForTranslateUri, _getLanguagesForTranslateQuery, null, response =>
{
Dictionary<string, Dictionary<string, Dictionary<string, string>>> jsonEntities;
Dictionary<string, Dictionary<string, string>> languages;
jsonEntities = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>();
using (Stream stream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(stream, this.GetResponseEncoding(response)))
{
Json.ParseInto(reader, jsonEntities);
}
}
results = jsonEntities.TryGetValue("translation", out languages) ? languages.Keys.ToArray() : new string[0];
});
return results;
}
public string GetLocalizedLanguageName(string locale, string language)
{
return this.GetLocalizedLanguageNames(locale, new[] { language })[0];
}
public string[] GetLocalizedLanguageNames(string locale, string[] languages)
{
string[] results;
// https://docs.microsoft.com/en-us/azure/cognitive-services/translator/reference/v3-0-languages?tabs=curl
results = null;
this.CheckToken();
this.ExecuteRequest(_getLanguageNamesUri, _getLanguagesForTranslateQuery, request => { request.Headers.Add(HttpRequestHeader.AcceptLanguage, locale); }, response =>
{
Dictionary<string, Dictionary<string, Dictionary<string, string>>> jsonEntities;
Dictionary<string, Dictionary<string, string>> responseLanguages;
jsonEntities = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>();
using (Stream stream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(stream, this.GetResponseEncoding(response)))
{
Json.ParseInto(reader, jsonEntities);
}
}
if (jsonEntities.TryGetValue("translation", out responseLanguages))
{
results = new string [languages.Length];
for (int i = 0; i < languages.Length; i++)
{
Dictionary<string, string> languageData;
if (responseLanguages.TryGetValue(languages[i], out languageData))
{
results[i] = languageData["name"];
}
}
}
else
{
results = new string [0];
}
});
return results;
}
public string Translate(string text, string from, string to)
{
string result;
string queryString;
// https://docs.microsoft.com/en-us/azure/cognitive-services/translator/reference/v3-0-translate?tabs=curl
result = null;
this.CheckToken();
queryString = "from=" + from + "&to=" + to;
this.ExecuteRequest(_translateUri, queryString, request =>
{
request.ContentType = "application/json";
request.Method = WebRequestMethods.Http.Post;
using (Stream stream = request.GetRequestStream())
{
using (TextWriter writer = new StreamWriter(stream, Encoding.UTF8))
{
Json.Write(writer, new[] { new TextInput(text) }, JsonOptions.DontWriteWhitespace | JsonOptions.Flush | JsonOptions.StrictParser);
}
}
}, response =>
{
TranslateResponse[] responses;
using (Stream stream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(stream, this.GetResponseEncoding(response)))
{
responses = Json.Parse<TranslateResponse[]>(reader);
}
}
result = null;
if (responses != null && responses.Length == 1)
{
TranslateResponse translation;
translation = responses[0];
if (translation.Translations != null && translation.Translations.Length == 1)
{
result = translation.Translations[0].Text;
}
}
});
return result;
}
private void CheckToken()
{
if (DateTime.UtcNow > _timestampWhenTokenExpires)
{
this.RefreshToken();
}
}
private HttpWebRequest CreateRequest(string uri, string query)
{
HttpWebRequest request;
if (!string.IsNullOrEmpty(query))
{
uri += _queryPrefix + "&" + query;
}
else
{
uri += _queryPrefix;
}
request = WebRequest.CreateHttp(uri);
if (!string.IsNullOrEmpty(_authorizationToken))
{
request.Headers.Add("Authorization", "Bearer " + _authorizationToken);
}
request.Accept = "application/json";
return request;
}
private void ExecuteRequest(string uri, string query, Action<HttpWebRequest> init, Action<HttpWebResponse> action)
{
HttpWebRequest request;
request = this.CreateRequest(uri, query);
try
{
init?.Invoke(request);
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
if (response.StatusCode == HttpStatusCode.OK)
{
action(response);
}
else
{
throw new InvalidOperationException("Unexpected response code.");
}
}
}
catch (WebException ex) when (ex.Status == WebExceptionStatus.ProtocolError && ex.Response is HttpWebResponse)
{
HttpWebResponse response;
response = (HttpWebResponse)ex.Response;
switch (response.StatusCode)
{
case HttpStatusCode.Unauthorized: throw new SecurityException("Invalid authorization key.", ex);
case HttpStatusCode.ServiceUnavailable: throw new InvalidOperationException("Quota exceeded.", ex);
default: throw;
}
}
}
private Encoding GetResponseEncoding(HttpWebResponse response)
{
return string.IsNullOrEmpty(response.CharacterSet) ? Encoding.UTF8 : Encoding.GetEncoding(response.CharacterSet);
}
private string GetResponseString(HttpWebResponse response)
{
Encoding encoding;
string result;
encoding = this.GetResponseEncoding(response);
using (Stream stream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(stream, encoding))
{
result = reader.ReadToEnd();
}
}
return result;
}
private void RefreshToken()
{
// https://docs.microsofttranslator.com/oauth-token.html
if (string.IsNullOrEmpty(_authorizationKey))
{
throw new InvalidOperationException("Authorization key not set.");
}
this.ExecuteRequest(_issueTokenUri, null, request =>
{
request.Method = WebRequestMethods.Http.Post;
request.Headers.Add("Ocp-Apim-Subscription-Key", _authorizationKey);
request.ContentLength = 0; // Must be set to avoid 411 response
}, response =>
{
_authorizationToken = this.GetResponseString(response);
_timestampWhenTokenExpires = DateTime.UtcNow.AddMinutes(_minutesUntilTokenExpires);
});
}
#endregion
}
}
Donate
This software may be used free of charge, but as with all free software there are costs involved to develop and maintain.
If this site or its services have saved you time, please consider a donation to help with running costs and timely updates.
Donate