当前位置: 首页 > article >正文

C# 阿里云短信接口调用(不使用SDK,单文件完成)

 支持单条和批量发送短信

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tech.CoreUtility;
using Tech.WebApi;

using System.Collections;
using System.Globalization;
using System.IO;
using System.Net;
using System.Security.Cryptography;


namespace Tech.TC.BLL
{
    /// <summary>
    /// 【相关文档】
    ///  RPC调用机制:https://help.aliyun.com/document_detail/315526.htm?spm=a2c4g.11186623.0.0.46b027b5vlfd0X
    ///  发送短信文档: https://help.aliyun.com/document_detail/419273.htm?spm=a2c4g.11186623.0.0.34374198G2b44u
    ///  短信接口文档:https://help.aliyun.com/document_detail/419298.html?spm=5176.25163407.help.dexternal.774dbb6eylDOx0
    /// </summary>
    public static class AliyunSmsHelper
    {
        /// <summary>
        ///     阿里云访问密钥
        /// </summary>
        public static string AccessKeyId = WorkBench.WebConfig["AccessKeyID"]; //用户标识
        public static string AccessKeySecret = WorkBench.WebConfig["AccessKeySecret"]; //用户密钥
        public static string SignName = WorkBench.WebConfig["SignName"]; //

        private static readonly string Separator = "&";
        public static string Url = "http://dysmsapi.aliyuncs.com?"; //短信接口地址

        /// <summary>
        ///     发送短信
        /// </summary>
        /// <param name="phone">手机号码</param>
        /// <param name="signName">短信签名</param>
        /// <param name="templateCode">模板编号</param>
        /// <param name="templateParam">模板变量</param>
        /// <returns></returns>
        public static string SendSms(string phone, string signName, string templateCode, string templateParam)
        {
            var dic = new Dictionary<string, string>();

            //公共请求参数
            dic.Add("Action", "SendSms");
            dic.Add("Version", "2017-05-25");
            dic.Add("Format", "JSON");
            dic.Add("AccessKeyId", AccessKeyId);
            dic.Add("SignatureNonce", Guid.NewGuid().ToString());
            dic.Add("Timestamp", DateTime.UtcNow.ToString("yyyy-MM-dd'T'HH:mm:ss'Z'"));
            dic.Add("SignatureMethod", "HMAC-SHA1");
            dic.Add("SignatureVersion", "1.0");

            //请求参数
            dic.Add("PhoneNumbers", phone);
            dic.Add("SignName", signName);
            dic.Add("TemplateCode", templateCode);
            dic.Add("TemplateParam", templateParam);

            //接口签名
            var signature = GetSignature(dic, "GET", AccessKeySecret);
            dic.Add("Signature", signature);

            var parms = "";
            foreach (var pair in dic) parms += pair.Key + "=" + PercentEncode(pair.Value) + "&"; //参数值需用阿里云约定编码方式进行编码
            parms = parms.TrimEnd('&');

            return HttpGet(Url + parms);
        }
        /// <summary>
        ///  批量发送短信
        /// </summary>
        /// <param name="phone">手机号码</param>
        /// <param name="signName">短信签名</param>
        /// <param name="templateCode">模板编号</param>
        /// <param name="templateParam">模板变量</param>
        /// <returns></returns>
        public static string SendBatchSms(List<string> phones, string templateCode, string templateParam)
        {
            var dic = new Dictionary<string, string>();

            //公共请求参数
            dic.Add("Action", "SendBatchSms");
            dic.Add("Version", "2017-05-25");
            dic.Add("Format", "JSON");
            dic.Add("AccessKeyId", AccessKeyId);
            dic.Add("SignatureNonce", Guid.NewGuid().ToString());
            dic.Add("Timestamp", DateTime.UtcNow.ToString("yyyy-MM-dd'T'HH:mm:ss'Z'"));
            dic.Add("SignatureMethod", "HMAC-SHA1");
            dic.Add("SignatureVersion", "1.0");

            //请求参数
            var signs = new string[phones.Count];
            Array.Fill<string>(signs, SignName);

            dic.Add("PhoneNumberJson", phones.ToJson());
            dic.Add("SignNameJson", signs.ToJson());
            dic.Add("TemplateCode", templateCode);
            dic.Add("TemplateParamJson", templateParam);

            //接口签名
            var signature = GetSignature(dic, "GET", AccessKeySecret);
            dic.Add("Signature", signature);

            var parms = "";
            foreach (var pair in dic) parms += pair.Key + "=" + PercentEncode(pair.Value) + "&"; //参数值需用阿里云约定编码方式进行编码
            parms = parms.TrimEnd('&');

            return HttpGet(Url + parms);
        }

        /// <summary>
        ///     发起网络请求
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string HttpGet(string url)
        {
            var encode = Encoding.UTF8;
            var request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "GET";
            request.ContentType = "text/html, application/xhtml+xml, */*";

            var response = (HttpWebResponse)request.GetResponse();
            var rs = response.GetResponseStream();
            var sr = new StreamReader(rs, encode);
            var result = sr.ReadToEnd();
            sr.Close();
            rs.Close();
            return result;
        }

        /// <summary>
        ///     签名算法
        /// </summary>
        /// <param name="signedParams"></param>
        /// <param name="method"></param>
        /// <param name="secret"></param>
        /// <returns></returns>
        public static string GetSignature(
            Dictionary<string, string> signedParams,
            string method,
            string secret)
        {
            var list = signedParams.Keys.ToList();

            list.Sort(StringComparer.Ordinal); //排序

            var builder = new StringBuilder();
            foreach (var key in list)
                if (signedParams[key] != null)
                    builder.Append("&").Append(PercentEncode(key)).Append("=").Append(PercentEncode(signedParams[key]));

            var builder2 = new StringBuilder();
            builder2.Append(method);
            builder2.Append(Separator);
            builder2.Append(PercentEncode("/"));
            builder2.Append(Separator);
            builder2.Append(PercentEncode(builder.ToString().Substring(1)));

            byte[] hash = { };
            using (var fromName = CryptoConfig.CreateFromName("HMACSHA1") as KeyedHashAlgorithm)
            {
                if (fromName != null)
                {
                    fromName.Key = Encoding.UTF8.GetBytes(secret + Separator);
                    hash = fromName.ComputeHash(Encoding.UTF8.GetBytes(builder2.ToString().ToCharArray()));
                }
            }

            return Convert.ToBase64String(hash);
        }

        /// <summary>
        ///     编码
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        private static string PercentEncode(string value)
        {
            if (value == null)
                return null;
            var stringBuilder = new StringBuilder();
            var str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";
            foreach (char ch in Encoding.UTF8.GetBytes(value))
                if (str.IndexOf(ch) >= 0)
                    stringBuilder.Append(ch);
                else
                    stringBuilder.Append("%").Append(string.Format(CultureInfo.InvariantCulture, "{0:X2}", (int)ch));
            return stringBuilder.ToString().Replace("+", "%20").Replace("*", "%2A").Replace("%7E", "~");
        }

        public static string ToForm(IDictionary filter)
        {
            if (filter == null)
                return string.Empty;
            var dictionary = filter.Keys.Cast<string>().ToDictionary(key => key, key => filter[key]);
            var dicOut = new Dictionary<string, string>();
            TileDict(dicOut, dictionary);
            var values = new List<string>();
            foreach (var keyValuePair in dicOut)
                if (!string.IsNullOrEmpty(keyValuePair.Value))
                    values.Add(PercentEncode(keyValuePair.Key) + "=" + PercentEncode(keyValuePair.Value));
            return string.Join("&", values.ToArray());
        }

        internal static void TileDict(Dictionary<string, string> dicOut, object obj, string parentKey = "")
        {
            if (obj == null)
                return;
            if (typeof(IDictionary).IsAssignableFrom(obj.GetType()))
            {
                foreach (var keyValuePair in ((IDictionary)obj).Keys.Cast<string>()
                         .ToDictionary(key => key, key => ((IDictionary)obj)[key]))
                {
                    var parentKey1 = parentKey + "." + keyValuePair.Key;
                    if (keyValuePair.Value != null)
                        TileDict(dicOut, keyValuePair.Value, parentKey1);
                }
            }
            else if (typeof(IList).IsAssignableFrom(obj.GetType()))
            {
                var num = 1;
                foreach (var obj1 in (IEnumerable)obj)
                {
                    TileDict(dicOut, obj1, parentKey + "." + num.ToSafeString());
                    ++num;
                }
            }
            else if (obj.GetType() == typeof(byte[]))
            {
                dicOut.Add(parentKey.TrimStart('.'), Encoding.UTF8.GetString((byte[])obj));
            }
            else
            {
                dicOut.Add(parentKey.TrimStart('.'), obj.ToSafeString(""));
            }
        }

        public static string ToSafeString(this object obj, string defaultStr = null)
        {
            if (obj == null)
                return defaultStr;
            try
            {
                return obj.ToString();
            }
            catch
            {
                return defaultStr;
            }
        }
    }

}

 调用方式如下:

AliyunSmsHelper.SendBatchSms(list, "SMS_xxxxxxx", count);

 参考文档:

C# 阿里云短信接口调用(不使用SDK,单文件完成)_c#阿里云 验证短信发送-CSDN博客

我也是参考他的,他没有写批量发送 


http://www.kler.cn/a/390754.html

相关文章:

  • 嵌入式硬件杂谈(一)-推挽 开漏 高阻态 上拉电阻
  • 【真题笔记】21年系统架构设计师案例理论点总结
  • 如何为电子课程创造创意
  • 设计模式-七个基本原则之一-迪米特法则 + 案例
  • 腾讯云nginx SSL证书配置
  • 【Threejs】相机控制器动画
  • Spring Spring Boot 常用注解总结
  • 前端零基础学习Day-Eight
  • 使用 Java 将 byte[] 转换为 File 对象并上传到外部服务器
  • 【已解决】Postman:Get请求传JSON数据
  • Kafka面试题(三)
  • html的week控件 获取周(星期)的第一天(周一)和最后一天(周日)
  • Pandas | 数据分析时将特定列转换为数字类型 float64 或 int64的方法
  • scikit-learn学习Day30
  • Java基础08(类与对象)
  • Java字符串的处理
  • SSE (Server-Sent Events) 服务器实时推送详解
  • 力扣-Hot100-哈希【算法学习day.30】
  • HTMLCSS: 日落卡片
  • MySQL核心业务大表归档过程
  • Attention is all you need详细解读
  • STM32问题集
  • ES5 和 ES6 数组的操作方法
  • ISAAC SIM踩坑记录--ubuntu 22.04操作系统安装
  • 小水电远程集控运维系统简介及应用价值
  • Unity WebGL交互通信