我在使用Aliyun 阿里云 ACS 机器翻译时遇到了SignatureDoesNotMatch 再次记录一下我的解决办法 也为其他遇到同样问题的伙伴指路

总体上来说阿里的文档做的不好,因此遇到不少困难,解决起来也不容易

阿里的介绍页
https://www.aliyun.com/product/ai/base_alimt?spm=5176.15007269.0.0.5e305d78mw1Tea

首先开通机器翻译服务
https://mt.console.aliyun.com/basic
在这里插入图片描述开通一个通用版翻译引擎专业版翻译引擎

然后去控制台 > 访问控制 https://ram.console.aliyun.com/overview 建立子账号和 AccessKey,这里的Key密码只显示一次 一定要保存好
在这里插入图片描述权限策略管理 加一个 规则
再把这个规则 授权 给刚建立的AccessKey

{
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "alimt:*",
            "Resource": "*"
        }
    ],
    "Version": "1"
}

关键的 开发指南
https://help.aliyun.com/document_detail/158244.html?spm=a2c4g.11186623.6.554.35c86720EBjoMf
在这里插入图片描述其实只看上面的就可以 下面是重复的 应该删掉

请求参数

名称 示例值 描述
Action TranslateGeneral 系统规定参数。取值:TranslateGeneral。
FormatType text 翻译文本的格式,html( 网页格式。设置此参数将对待翻译文本以及翻译后文本按照html格式进行处理)、text(文本格式。设置此参数将对传入待翻译文本以及翻译后结果不做文本格式处理,统一按纯文本格式处理。
Scene general 通用版本默认是:general,医疗(medical),社交(social)
SourceLanguage en 原文语言
TargetLanguage zh 需要翻译的内容
SourceText Hello World! 待翻译文本

返回数据

名称 类型 示例值 描述
Code Integer 200 错误码
Data Struct 封装了返回的翻译结果
Translated String 你好世界 翻译结果
Message String success 返回信息
RequestId GUID 86D18195-D89C-4C8C-9DC4-5FCE789CE6D5 请求ID

也是比较清晰的 ,然后就是httprequest的签名算法, 一般的机器翻译基本上都采用类似Google的随机数加APIKey加待翻译文字的算法,但是阿里不太一样,有一套自己的签名算法https://help.aliyun.com/document_detail/108552.html?spm=a2c4g.11186623.6.552.5ae042e0XtV1jT
而且这套算法是全阿里平台通用的 并且不包含待翻译文字

可以通过文档页面和Open API进行调试 这一点很方便
https://api.aliyun.com/#/?product=alimt&api=TranslateGeneral
在这里插入图片描述页面直接测试还给出了HTTP响应以及生成了代码

在这里插入图片描述
给出的代码如下 .NET

using System;
using System.Collections.Generic;
using Aliyun.Acs.Core;
using Aliyun.Acs.Core.Exceptions;
using Aliyun.Acs.Core.Profile;
using Aliyun.Acs.alimt.Model.V20181012;

namespace alimtDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            IClientProfile profile = DefaultProfile.GetProfile("cn-hangzhou", "<accessKeyId>", "<accessSecret>");
            DefaultAcsClient client = new DefaultAcsClient(profile);

            var request = new TranslateGeneralRequest();
            request.FormatType = "text";
            request.SourceLanguage = "en";
            request.TargetLanguage = "zh";
            request.SourceText = "Hello World!";
            try {
                var response = client.GetAcsResponse(request);
                Console.WriteLine(System.Text.Encoding.Default.GetString(response.HttpResponse.Content));
            }
            catch (ServerException e)
            {
                Console.WriteLine(e);
            }
            catch (ClientException e)
            {
                Console.WriteLine(e);
            }
        }
    }
}

接下来换在IDE中测试
首先 GitHub下载SDK
https://github.com/aliyun/aliyun-openapi-net-sdk
需要 aliyun-net-sdk-alimt 和 aliyun-net-sdk-core
编译后得到aliyun-net-sdk-alimt.dll和aliyun-net-sdk-core.dll (编译时需要newtonsoft json)

运行上面的源码,你就会得到 SignatureDoesNotMatch 的错误
节约时间原因我就不多说了 解决方法如下:
var request = new TranslateGeneralRequest(); 之后

  1. 添加 request.Method = Aliyun.Acs.Core.Http.MethodType.POST;
  2. 添加 request.ActionName = “TranslateGeneral”;

其实从上面的参数表里面我们已经看到Action是一个必要的参数,因此必须明确声明,但是阿里的页面调试器默认赋值了这个参数 因此 在线版不会错 但是IDE测试出错

同理默认httprequest是GET,阿里机器翻译API只接受POST

添加后编译通过得到结果是一个byte[]数组 用UTF-8转换得到

{
	"RequestId": "75D29BFF-9D06-4069-B35A-BFA41DF2C075",
	"Data": {
		"Translated": "你好世界!"
	},
	"Code": "200"
}

用json转换一下

dynamic TempResult = JsonConvert.DeserializeObject(resultStr);
string resultText = Convert.ToString(TempResult["Data"]["Translated"]);

得到最终翻译结果

最后完整代码

using System;
using System.Collections.Generic;
using Aliyun.Acs.Core;
using Aliyun.Acs.Core.Exceptions;
using Aliyun.Acs.Core.Profile;
using Aliyun.Acs.alimt.Model.V20181012;
using Newtonsoft.Json;
namespace alimtDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            IClientProfile profile = DefaultProfile.GetProfile("cn-hangzhou", "<accessKeyId>", "<accessSecret>");
            DefaultAcsClient client = new DefaultAcsClient(profile);

            var request = new TranslateGeneralRequest();
            request.FormatType = "text";
            request.SourceLanguage = "en";
            request.TargetLanguage = "zh";
            request.SourceText = "Hello World!";
            request.Scene = "general";
            request.Method = Aliyun.Acs.Core.Http.MethodType.POST;
            request.ActionName = "TranslateGeneral";
            try {
                var response = client.GetAcsResponse(request);
                string resultStr = System.Text.Encoding.UTF-8.GetString(response.HttpResponse.Content);
                
                dynamic TempResult = JsonConvert.DeserializeObject(resultStr);
                string resultText = Convert.ToString(TempResult["Data"]["Translated"]);
                Console.WriteLine(resultText);
                Console.ReadLine();
            }
            catch (ServerException e)
            {
                Console.WriteLine(e);
            }
            catch (ClientException e)
            {
                Console.WriteLine(e);
            }
        }
    }
}
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐