自己试了下对接没成功
签名算法用阿里提供的RPC,并通过了阿里官方DEMO,算法没问题
阿里云RPC OpenAPI请求的组成部分是怎样的_阿里云SDK-阿里云帮助中心
是看着官方API开发的
调用GetBatchTranslate批量翻译机器_机器翻译-阿里云帮助中心
然后我发现我怎么试都无法成功,总是提示时间戳失效?
我要怎么修改代码才能实现这个功能?不使用官方的SDK!
public class Program {
public static API信息 data;
public static void Main(string[] args) {
data = new API信息();
data.KEY = "AccessKey ID";
data.秘钥 = "AccessKey Secret ";
data.源语言 = "en";
data.目标语言 = "zh";
string Json = HTTP批量机翻(new string[] { "hello", "world" });
Console.WriteLine(Json);
Console.ReadLine();
}
public static string HTTP批量机翻(string[] texts) {
string url = "http://mt.cn-hangzhou.aliyuncs.com/api/translate/web/ecommerce?";
string 请求类型 = "GET";
//设置SourceText
Dictionary<string, string> ID_文本 = new Dictionary<string, string>();
int index = 0;
foreach (string text in texts) {
ID_文本.Add((index++).ToString(), text);
}
Dictionary<string, string> 请求参数 = new Dictionary<string, string>();
//请求参数.Add("Action", "GetBatchTranslate");
请求参数.Add("FormatType", "text");
请求参数.Add("TargetLanguage", data.目标语言);
请求参数.Add("SourceLanguage", data.源语言);
请求参数.Add("Scene", "general");//专业版社交:social,通用版:general
请求参数.Add("ApiType", "translate_standard");//通用版:translate_standard,专业版:translate_ecommerce
请求参数.Add("SourceText", JsonConvert.SerializeObject(ID_文本));
#region 计算公共请求参数
Dictionary<string, string> 公共请求参数 = new Dictionary<string, string>();
foreach (var kv in 请求参数) {
公共请求参数.Add(kv.Key, kv.Value);
}
RFC3986 rfc = new RFC3986();
公共请求参数.Add("Action", "GetBatchTranslate");
公共请求参数.Add("Version", "2018-10-12");
公共请求参数.Add("Format", "JSON");
公共请求参数.Add("AccessKeyId", data.KEY);
公共请求参数.Add("SignatureNonce", 随机数生成(14));
公共请求参数.Add("Timestamp", DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ssZ"));
公共请求参数.Add("SignatureMethod", "HMAC-SHA1");
公共请求参数.Add("SignatureVersion", "1.0");
#region 签名算法
//首字母排序b,a,C => C,a,b,然后进行RFC3896的UTF-8编码
Dictionary<string, string> 临时请求参数 = (from kv in 公共请求参数
orderby kv.Key[0], kv.Key
select kv).ToDictionary(t1 => rfc.编码(t1.Key), t2 => rfc.编码(t2.Value));
StringBuilder 请求头 = new StringBuilder(url);
StringBuilder 公共参数体 = new StringBuilder();
for (int i = 0; i < 临时请求参数.Count; i++) {
var kv = 临时请求参数.ElementAt(i);
公共参数体.Append(kv.Key).Append("=").Append(kv.Value);
if (i != 临时请求参数.Count - 1) {
公共参数体.Append("&");
}
}
string 签名字符串 = $"{请求类型}&{rfc.编码("/")}&{rfc.编码(公共参数体.ToString())}";
string signature = HMACSHA1加密(签名字符串, data.秘钥 + "&");//用秘钥加密签名串并返回BASE64
#endregion
公共请求参数.Add("Signature", signature);//请求签名
#endregion
StringBuilder 链接 = new StringBuilder(url);
foreach (var kv in 请求参数) {
链接.Append(kv.Key).Append('=').Append(kv.Value).Append('&');
}
for (int i = 0; i < 公共请求参数.Count; i++) {
var kv = 公共请求参数.ElementAt(i);
链接.Append(kv.Key).Append('=').Append(kv.Value);
if (i != 公共请求参数.Count - 1) {
链接.Append("&");
}
}
HttpWebRequest request = WebRequest.Create(链接.ToString()) as HttpWebRequest;
request.KeepAlive = false;
request.Method = 请求类型;
request.Timeout = 6000;
HttpWebResponse response;
string 返回值 = null;
try {
using (response = (HttpWebResponse)request.GetResponse()) {
using (Stream myResponseStream = response.GetResponseStream()) {
using (StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"))) {
返回值 = myStreamReader.ReadToEnd();
}
}
}
} catch (Exception ex) {
throw ex;
} finally {
request.Abort();
}
return 返回值;
}
/// <summary>
/// HMACSHA1加密
/// </summary>
/// <param name="text">要加密的原串</param>
///<param name="key">私钥</param>
/// <returns></returns>
private static string HMACSHA1加密(string text, string key) {
//HMACSHA1加密
HMACSHA1 hmacsha1 = new HMACSHA1();
hmacsha1.Key = System.Text.Encoding.UTF8.GetBytes(key);
byte[] dataBuffer = System.Text.Encoding.UTF8.GetBytes(text);
byte[] hashBytes = hmacsha1.ComputeHash(dataBuffer);
return Convert.ToBase64String(hashBytes);
}
public static string 随机数生成(int 长度) {
string buffer = "0123456789";// 随机字符中也可以为汉字(任何)
StringBuilder sb = new StringBuilder();
Random r = new Random();
int range = buffer.Length;
for (int i = 0; i < 长度; i++) {
sb.Append(buffer.Substring(r.Next(range), 1));
}
return sb.ToString();
}
}
public class API信息 {
public string KEY { get; set; }
public string 秘钥 { get; set; }
public string 源语言 { get; set; }
public string 目标语言 { get; set; }
}
public class RFC3986 {
public string 编码(string str) {
StringBuilder sb = new StringBuilder();
var urf8Bytes = Encoding.UTF8.GetBytes(str);
foreach (var item in urf8Bytes) {
if (IsReverseChar((char)item)) {
sb.Append('%');
sb.Append(item.ToString("X2"));
} else
sb.Append((char)item);
}
return sb.ToString();
}
private bool IsReverseChar(char c) {
return !((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')
|| c == '-' || c == '_' || c == '.' || c == '~');
}
}