Google Translate V2 не может передавать большие текстовые переводы из C # - PullRequest
6 голосов
/ 24 февраля 2012

Я реализовал код C #, используя API-интерфейс Google Translation V2 с методом GET. Он успешно переводит небольшие тексты, но при увеличении длины текста и длине в 1800 символов (включая параметры URI) я получаю сообщение об ошибке «слишком большой URI».

Хорошо, я записал все пути и исследовал проблему на нескольких страницах, размещенных в Интернете. Все они ясно говорят, что метод GET должен быть переопределен для имитации метода POST (который предназначен для обеспечения поддержки 5000 символов URI), но нет способа найти пример кода для него.

Кто-нибудь имеет какой-либо пример или может предоставить некоторую информацию?

[ РЕДАКТИРОВАТЬ ] Вот код, который я использую:

String apiUrl = "https://www.googleapis.com/language/translate/v2?key={0}&source={1}&target={2}&q={3}";
            String url = String.Format(apiUrl, Constants.apiKey, sourceLanguage, targetLanguage, text);
            Stream outputStream = null;

        byte[] bytes = Encoding.ASCII.GetBytes(url);

        // create the http web request
        HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
        webRequest.KeepAlive = true;
        webRequest.Method = "POST";
        // Overrride the GET method as documented on Google's docu.
        webRequest.Headers.Add("X-HTTP-Method-Override: GET");
        webRequest.ContentType = "application/x-www-form-urlencoded";

        // send POST
        try
        {
            webRequest.ContentLength = bytes.Length;
            outputStream = webRequest.GetRequestStream();
            outputStream.Write(bytes, 0, bytes.Length);
            outputStream.Close();
        }
        catch (HttpException e)
        {
            /*...*/
        }

        try
        {
            // get the response
            HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
            if (webResponse.StatusCode == HttpStatusCode.OK && webRequest != null)
            {
                // read response stream 
                using (StreamReader sr = new StreamReader(webResponse.GetResponseStream(), Encoding.UTF8))
                {
                    string lista = sr.ReadToEnd();

                    DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(TranslationRootObject));
                    MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(lista));
                    TranslationRootObject tRootObject = (TranslationRootObject)serializer.ReadObject(stream);
                    string previousTranslation = string.Empty;

                    //deserialize
                    for (int i = 0; i < tRootObject.Data.Detections.Count; i++)
                    {
                        string translatedText = tRootObject.Data.Detections[i].TranslatedText.ToString();
                        if (i == 0)
                        {
                            text = translatedText;
                        }
                        else
                        {
                            if (!text.Contains(translatedText))
                            {
                                text = text + " " + translatedText;
                            }
                        }
                    }
                    return text;
                }
            }
        }
        catch (HttpException e)
        {
            /*...*/
        }

        return text;
    }

Ответы [ 3 ]

7 голосов
/ 24 февраля 2012

Очевидно, что использование WebClient не будет работать, так как вы не можете изменять заголовки при необходимости, согласно документации :

Примечание: Вы также можете использовать POST для вызова API, если вы хотите отправить больше данных в одном запросе. Параметр q в теле POST должен содержать не более 5К символов. Чтобы использовать POST, вы должны использовать заголовок X-HTTP-Method-Override, чтобы указать Translate API для обработки запроса как GET (используйте X-HTTP-Method-Override: GET).

Вы можете использовать WebRequest, но вам нужно добавить заголовок X-HTTP-Method-Override:

var request = WebRequest.Create (uri);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.Headers.Add("X-HTTP-Method-Override", "GET");

var body = new StringBuilder();
body.Append("key=SECRET");
body.AppendFormat("&source={0}", HttpUtility.UrlEncode(source));
body.AppendFormat("&target={0}", HttpUtility.UrlEncode(target));
 //--
body.AppendFormat("&q={0}", HttpUtility.UrlEncode(text));

var bytes = Encoding.ASCII.GetBytes(body.ToString());
if (bytes.Length > 5120) throw new ArgumentOutOfRangeException("text");

request.ContentLength = bytes.Length;
using (var output = request.GetRequestStream())
{
    output.Write(bytes, 0, bytes.Length);
}
1 голос
/ 22 января 2015

Принятый ответ устарел.Теперь вы можете успешно использовать WebClient (* .net 4.5), чтобы POST API google translate, установив заголовок X-HTTP-Method-Override.

Вот код, который покажет вам, как.

using (var webClient = new WebClient())
{
    webClient.Headers.Add("X-HTTP-Method-Override", "GET");
    var data = new NameValueCollection() 
    { 
        { "key", GoogleTranslateApiKey }, 
        { "source", "en" }, 
        { "target", "fr"}, 
        { "q", "<p>Hello World</p>" } 
    };
    try
    {
        var responseBytes = webClient.UploadValues(GoogleTranslateApiUrl, "POST", data);
        var json = Encoding.UTF8.GetString(responseBytes);
        var result = JsonConvert.DeserializeObject<dynamic>(json);
        var translation = result.data.translations[0].translatedText;
    }
    catch (Exception ex)
    {
        loggingService.Error(ex.Message);
    }
} 
0 голосов
/ 24 февраля 2012

? Какие? постить с помощью C # тривиально - это прямо в документации.

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
{
    // Set type to POST
    request.Method = "POST";

С этого момента вы в основном помещаете данные в поля fom в потоке контента.

Это не "имитировать почтовое собрание", оно полностью выполняет почтовый запрос в соответствии со спецификациями.

Btw. где сюда входит json? Вы говорите "в C #". Нет необходимости использовать JSON?

...