C# 使用GET和POST(v1签名方式)以及SDK的方式调用腾讯云人像动漫化接口,包含设置代理

本文介绍了在调用腾讯云的人像动漫化API时遇到的签名错误问题,强调了签名参数顺序、URL编码等关键点,并提供了C#代码示例,包括常规的GET和POST请求以及使用SDK的方式。
摘要由CSDN通过智能技术生成

声明:此内容仅供学习交流使用,不用于商业用途,如果涉及侵权,联系作者删除。

最近在调用腾讯云的人像动漫化接口,感觉挺好玩的,自己去看文档写了一下,遇到了各种问题,最后都解决了 ,遇到最多的就是签名错误(AuthFailure.SignatureFailure),都是看文档不看完导致的,要注意签名参数的顺序、请求参数的值必须进行url编码之内的,甚至我还sb的把调用签名加密方法的参数顺序搞混了,害得我找了好久 -_-||    ,还好都解决了。下面展示代码:

常规的GET和POST的请求方式:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace ConsoleApp2
{
    class Main_3
    {
        static void Main(string[] args)
        {
            string action = "FaceCartoonPic";//接口名称
            string secretid = "你的SecretId";//SecretId
            string secretKey = "你的SecretKey";//SecretKey
            string version = "2020-03-04";//版本
            string region = "ap-guangzhou";//云服务器区域,离你越近越好
            string url = "https://ft.tencentcloudapi.com/";//接口地址
            string host = "ft.tencentcloudapi.com";//域名
            Random rd = new Random();
            string nonce = rd.Next().ToString();///随机正整数,用于防止重放攻击
            string timestamp = GetCurrentTimestamp();//时间戳
            string filename = @"F:\XXX\XXX\xy.jpg";//图片路径
            string imgbase64 = ImgToBase64(filename);//base64字串要是图片转base64的方式才行,文件转base64的方式会报URL过长的错

            Dictionary<string, string> postdata = new Dictionary<string, string>();
            postdata.Add("Action", action);
            postdata.Add("Image", imgbase64);
            postdata.Add("Language", "zh-CN");
            postdata.Add("Nonce", nonce);
            postdata.Add("Region", region);
            postdata.Add("SecretId", secretid);
            //dic.Add("SignatureMethod", "HmacSHA1");//加密方式 默认HmacSHA1
            postdata.Add("Timestamp", timestamp);
            postdata.Add("Version", version);
            string data = string.Empty;
            SortedDictionary<string, string> sortDc = new SortedDictionary<string, string>(postdata, StringComparer.Ordinal);//排序 加密的数据必须排序
            foreach (var item in sortDc)
            {
                if (!string.IsNullOrEmpty(data))
                {
                    data += "&";
                }
                data += string.Format("{0}={1}", item.Key, item.Value);
            }
            string qm = $"POST{host}/?" + data;//POST请求的加密前字串
            string signature = Sign(secretKey, qm);
            postdata.Add("Signature", signature);//添加上签名字段
            data = string.Empty;
            foreach (var item in postdata)
            {
                if (!string.IsNullOrEmpty(data))
                {
                    data += "&";
                }
                data += string.Format("{0}={1}", item.Key, HttpUtility.UrlEncode(item.Value));//参数的值必须要进行URL编码
            }
            Dictionary<string, string> headers = new Dictionary<string, string>();
            //headers.Add("Host", host);//请求头带有Host
            string res = Post(url, data);//Post的请求方式
            //string res = Get(url + "?" + data);Get的请求方式
            Console.WriteLine(res);
            Console.ReadKey();
        }
        /// <summary>
        /// 进行SHA1签名加密
        /// </summary>
        /// <param name="signKey">secretKey</param>
        /// <param name="secret">需要加密的字符串</param>
        /// <returns></returns>
        public static string Sign(string signKey, string secret)
        {
            string signRet = string.Empty;
            using (HMACSHA1 mac = new HMACSHA1(Encoding.UTF8.GetBytes(signKey)))
            {
                byte[] hash = mac.ComputeHash(Encoding.UTF8.GetBytes(secret));
                signRet = Convert.ToBase64String(hash);
            }
            return signRet;
        }
        /// <summary>
        /// 图片转Base64
        /// </summary>
        /// <param name="filename">文件路径</param>
        /// <returns></returns>
        public static string ImgToBase64(string filename)
        {
            string base64_3;
            MemoryStream ms = new MemoryStream();
            try
            {
                Bitmap bmp = new Bitmap(filename);
                bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                byte[] arr = new byte[ms.Length];
                ms.Position = 0;
                ms.Read(arr, 0, (int)ms.Length);
                base64_3 = Convert.ToBase64String(arr);
                bmp.Dispose();
                return base64_3;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
            finally
            {
                ms.Close();

            }
        }
        /// <summary>
        ///     获取时间戳
        /// </summary>
        /// <returns></returns>
        public static string GetCurrentTimestamp()
        {
            //TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            //return Convert.ToInt64(ts.TotalSeconds).ToString();
            var number = 10000 * 1000;
            return ((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / number).ToString();
        }
        /// <summary>
        /// 常规Post请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public static string Post(string url, string postData)
        {
            // 创建一个WebRequest对象
            WebRequest request = WebRequest.Create(url);

            // 设置请求方法为POST
            request.Method = "POST";

            // 将数据转换为字节数组
            byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(postData);

            // 设置请求内容类型
            request.ContentType = "application/x-www-form-urlencoded";

            //设置代理
            request.Proxy = new WebProxy("代理IP", 端口);

            // 设置请求内容长度
            request.ContentLength = byteArray.Length;

            // 获取请求流并写入数据
            Stream dataStream = request.GetRequestStream();
            dataStream.Write(byteArray, 0, byteArray.Length);
            dataStream.Close();

            // 发送请求并获取响应
            WebResponse response = request.GetResponse();

            // 读取响应流
            StreamReader reader = new StreamReader(response.GetResponseStream());
            string responseText = reader.ReadToEnd();

            // 关闭响应流和请求对象
            reader.Close();
            response.Close();

            return responseText;
        }
        /// <summary>
        /// 常规Get请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public static string Get(string url)
        {
            string result = "";
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "GET";
            request.Proxy = new WebProxy("代理IP", 端口);//设置代理
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                using (Stream stream = response.GetResponseStream())
                {
                    using (StreamReader reader = new StreamReader(stream))
                    {
                        result = reader.ReadToEnd();
                    }
                }
            }
            return result;
        }
    }
}

使用SDK的方式:

        需要去neget上安装:TencentCloud

然后引用上,下面是代码:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using TencentCloud.Common;
using TencentCloud.Common.Profile;
using TencentCloud.Ft.V20200304;
using TencentCloud.Ft.V20200304.Models;

namespace ConsoleApp2
{
    class Main_1
    {
        static void Main(string[] args)
        {
            try
            {
                // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
                Credential cred = new Credential
                {
                    SecretId = "你的SecretId",
                    SecretKey = "你的SecretKey"
                };
                // 实例化一个client选项,可选的,没有特殊需求可以跳过
                ClientProfile clientProfile = new ClientProfile();
                // 实例化一个http选项,可选的,没有特殊需求可以跳过
                HttpProfile httpProfile = new HttpProfile();
                httpProfile.Endpoint = ("ft.tencentcloudapi.com");
                clientProfile.HttpProfile = httpProfile;
                clientProfile.HttpProfile.WebProxy = "http://你的代理IP:端口";//设置代理
                // 实例化要请求产品的client对象,clientProfile是可选的
                FtClient client = new FtClient(cred, "ap-guangzhou", clientProfile);
                // 实例化一个请求对象,每个接口都会对应一个request对象
                FaceCartoonPicRequest req = new FaceCartoonPicRequest();
                string filename = @"F:\XXX\XXX\xy.jpg";//图片路径
                string imgbase64 = ImgToBase64(filename);
                req.Image = imgbase64;
                // 返回的resp是一个FaceCartoonPicResponse的实例,与请求对象对应
                FaceCartoonPicResponse resp = client.FaceCartoonPicSync(req);
                // 输出json格式的字符串回包
                string res = AbstractModel.ToJsonString(resp);
                Console.WriteLine(res);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
            Console.ReadKey();
        }
        static string ImgToBase64(string filename)
        {
            string base64_3;
            MemoryStream ms = new MemoryStream();
            try
            {
                Bitmap bmp = new Bitmap(filename);
                bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                byte[] arr = new byte[ms.Length];
                ms.Position = 0;
                ms.Read(arr, 0, (int)ms.Length);
                base64_3 = Convert.ToBase64String(arr);
                bmp.Dispose();
                return base64_3;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
            finally
            {
                ms.Close();

            }
        }
    }
}

 代码就是这些,挺简单的,就是调接口时一些小细节没注意到,导致了很多次都是失败。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值