2

我正在尝试使用 Bing Translate 的 API 将一些英文文本翻译成中文。

我的代码基本上是MSDN上提供的,尽管做了一些修改。

using System;
using System.Text;
using System.Net;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Web;
using System.ServiceModel.Channels;
using System.ServiceModel;

namespace AutoTranslate2
{
    public class Translator
    {
        private string authToken;

        public Translator(string clientId, string clientSecret)
        {
            AdmAccessToken admToken;

            AdmAuthentication admAuth = new AdmAuthentication("clientId", "client secret");

            admToken = admAuth.GetAccessToken();
            DateTime tokenReceived = DateTime.Now;
            this.authToken = "Bearer " + admToken.access_token;
        }

        public string TranslateMethod(
            string text,
            string inputLang = "en",
            string outputLang = "zh-CHS", // Chinese, simplified ('zh-CHT' is traditional Chinese)
            string inputType = "text/html",
            string outputType = "general")
        {
            // Add TranslatorService as a service reference, Address:http://api.microsofttranslator.com/V2/Soap.svc
            TranslatorService.LanguageServiceClient client = new TranslatorService.LanguageServiceClient();
            //Set Authorization header before sending the request
            HttpRequestMessageProperty httpRequestProperty = new HttpRequestMessageProperty();
            httpRequestProperty.Method = "POST";
            httpRequestProperty.Headers.Add("Authorization", this.authToken);

            // Creates a block within which an OperationContext object is in scope.
            string translationResult;
            using (OperationContextScope scope = new OperationContextScope(client.InnerChannel))
            {
                OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
                //Keep appId parameter blank as we are sending access token in authorization header.
                translationResult = client.Translate("", "<p>" + text + "</p>", inputLang, outputLang, inputType, outputType);
            }
            return translationResult;
        }
    }

    [DataContract]
    public class AdmAccessToken
    {
        [DataMember]
        public string access_token { get; set; }
        [DataMember]
        public string token_type { get; set; }
        [DataMember]
        public string expires_in { get; set; }
        [DataMember]
        public string scope { get; set; }
    }

    public class AdmAuthentication
    {
        public static readonly string DatamarketAccessUri = "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13";
        private string clientId;
        private string clientSecret;
        private string request;

        public AdmAuthentication(string clientId, string clientSecret)
        {
            this.clientId = clientId;
            this.clientSecret = clientSecret;
            //If clientid or client secret has special characters, encode before sending request
            this.request = string.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=http://api.microsofttranslator.com", HttpUtility.UrlEncode(clientId), HttpUtility.UrlEncode(clientSecret));
        }

        public AdmAccessToken GetAccessToken()
        {
            return HttpPost(DatamarketAccessUri, this.request);
        }

        private AdmAccessToken HttpPost(string DatamarketAccessUri, string requestDetails)
        {
            //Prepare OAuth request 
            WebRequest webRequest = WebRequest.Create(DatamarketAccessUri);
            webRequest.ContentType = "application/x-www-form-urlencoded";
            webRequest.Method = "POST";
            byte[] bytes = Encoding.ASCII.GetBytes(requestDetails);
            webRequest.ContentLength = bytes.Length;
            using (Stream outputStream = webRequest.GetRequestStream())
            {
                outputStream.Write(bytes, 0, bytes.Length);
            }
            WebResponse webResponse = webRequest.GetResponse();
            using (webResponse)
            {
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(AdmAccessToken));
                //Get deserialized object from JSON stream
                AdmAccessToken token = (AdmAccessToken)serializer.ReadObject(webResponse.GetResponseStream());
                return token;
            }
        }
    }
}

...在我的代码中的其他地方,我确实...

Translator t = new Translator(client_id, secret);
string output = t.TranslateMethod(text);

但是,代码总是返回异常:

Unhandled Exception: System.Net.WebException: The remote server returned an error: (400) Bad Request.
   at System.Net.HttpWebRequest.GetResponse()
   at AutoTranslate2.AdmAuthentication.HttpPost(String DatamarketAccessUri, String requestDetails) in C:\Users\Deflect\AutoTranslate2\AutoTranslate2\Translate.cs:line 102
   at AutoTranslate2.AdmAuthentication.GetAccessToken() in C:\Users\Deflect\AutoTranslate2\AutoTranslate2\Translate.cs:line 87
   at AutoTranslate2.Translator..ctor(String clientId, String clientSecret) in C:\Users\Deflect\AutoTranslate2\AutoTranslate2\Translate.cs:line 26
   at AutoTranslate2.Chinese.Parse(String rawText) in C:\Users\Deflect\AutoTranslate2\AutoTranslate2\Parse.cs:line 68
   at AutoTranslate2.Program.Main(String[] args) in C:\Users\Deflect\AutoTranslate2\AutoTranslate2\Program.cs:line 19

我将是第一个承认我真的不知道我的代码在做什么的人,因为我主要是从 MSDN 复制和粘贴的——有人知道我的代码为什么返回异常,以及如何让它工作吗?

4

1 回答 1

2

就是这一行:

AdmAuthentication admAuth = new AdmAuthentication("clientId", "client secret"); 

我忘记将示例中的字符串与实际变量交换。

于 2012-07-05T22:02:14.590 回答