2012-02-24 95 views
6

我已經使用Google翻譯V2 API與GET方法實現了C#代碼。 它成功地翻譯了小文本,但是當增加文本長度並且需要1800個字符(包括URI參數)時,我得到了「URI太大」的錯誤。Google翻譯V2不能包含來自C#的大文本翻譯

好吧,我燒掉了所有的路徑,並調查了在互聯網上發佈的多個頁面的問題。他們都清楚地說GET方法應該被覆蓋以模擬POST方法(它旨在提供對5,000個字符的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; 
    } 
+0

你能告訴我們你現在使用的代碼嗎?如果您使用「WebClient」與「WebRequest」,該策略有點不同。 – user7116 2012-02-24 14:40:47

回答

7

顯然使用WebClient根據需要將無法正常工作,因爲你不能改變標題,per the documentation

Note: You can also use POST to invoke the API if you want to send more data in a single request. The q parameter in the POST body must be less than 5K characters. To use POST, you must use the X-HTTP-Method-Override header to tell the Translate API to treat the request as a GET (use 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); 
} 
+0

感謝您的快速響應。我已經添加了我正在執行的代碼。我還深入瞭解了您發佈的代碼,並且能夠按照您的指示更新我的帖子。但是,執行「request.GetResponse();」會引發以下錯誤:「遠程服務器返回錯誤:(400)錯誤請求」。將研究這一點。 – G21 2012-02-24 15:46:50

+0

@ George_21:您需要擺脫URL中的參數,並將它們全部放在帖子正文中。 – user7116 2012-02-24 16:17:06

+1

你是我的英雄! :P。我終於能夠按照你的建議重新編寫我的代碼,並添加了一個缺失的行:「request.ContentType =」application/x-www-form-urlencoded「;真的很感謝你對此的幫助!Thankssss! – G21 2012-02-24 18:08:59

-3

?什麼?使用C#發佈是微不足道的 - 它就在文檔中。

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

從那裏你基本上把數據放到fom字段到內容流中。

這不是「模擬帖子的方法」,它完全按照規範做了一個帖子請求。

Btw。 JSON在哪裏進入?你說「用C#」。沒有必要使用json?

+0

不處理「X-HTTP-Method-Override」部分。 – Suma 2012-07-04 14:13:41

1

接受的答案似乎已過時。您現在可以成功使用WebClient(.net 4.5)到POST,以確保設置X-HTTP-Method-Override標題的谷歌翻譯API。

這是一些代碼,告訴你如何。

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); 
    } 
}