博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
.net core 使用阿里云短信发送SMS
阅读量:4920 次
发布时间:2019-06-11

本文共 8562 字,大约阅读时间需要 28 分钟。

阿里云官方的skd(aliyun-net-sdk-core,aliyun-net-sdk-dysmsapi)在dnc中发送短信会出错,nuget上的包貌似也一样不管用。直接改下sdk当然也可以,但就发个短信,官方的sdk实在是有点繁杂,其实可以简单化,一个类就搞定。

1 using Newtonsoft.Json;  2 using System;  3 using System.Collections.Generic;  4 using System.Globalization;  5 using System.Net;  6 using System.Net.Http;  7 using System.Security.Cryptography;  8 using System.Text;  9 using System.Threading.Tasks; 10 using System.Web; 11  12 namespace Vino.Core.Communication.SMS 13 { 14     public class AliyunSmsSender : ISmsSender 15     { 16         private string RegionId = "cn-hangzhou"; 17         private string Version = "2017-05-25"; 18         private string Action = "SendSms"; 19         private string Format = "JSON"; 20         private string Domain = "dysmsapi.aliyuncs.com"; 21  22         private int MaxRetryNumber = 3; 23         private bool AutoRetry = true; 24         private const string SEPARATOR = "&"; 25         private int TimeoutInMilliSeconds = 100000; 26  27         private string AccessKeyId; 28         private string AccessKeySecret; 29  30         public AliyunSmsSender(string accessKeyId, string accessKeySecret) 31         { 32             this.AccessKeyId = accessKeyId; 33             this.AccessKeySecret = accessKeySecret; 34         } 35  36         ///  37         /// 发送短信 38         ///  39         public async Task<(bool success, string response)> Send(SmsObject sms) 40         { 41             var paramers = new Dictionary
(); 42 paramers.Add("PhoneNumbers", sms.Mobile); 43 paramers.Add("SignName", sms.Signature); 44 paramers.Add("TemplateCode", sms.TempletKey); 45 paramers.Add("TemplateParam", JsonConvert.SerializeObject(sms.Data)); 46 paramers.Add("OutId", sms.OutId); 47 paramers.Add("AccessKeyId", AccessKeyId); 48 49 try 50 { 51 string url = GetSignUrl(paramers, AccessKeySecret); 52 53 int retryTimes = 1; 54 var reply = await HttpGetAsync(url); 55 while (500 <= reply.StatusCode && AutoRetry && retryTimes < MaxRetryNumber) 56 { 57 url = GetSignUrl(paramers, AccessKeySecret); 58 reply = await HttpGetAsync(url); 59 retryTimes++; 60 } 61 62 if (!string.IsNullOrEmpty(reply.response)) 63 { 64 var res = JsonConvert.DeserializeObject
>(reply.response); 65 if (res != null && res.ContainsKey("Code") && "OK".Equals(res["Code"])) 66 { 67 return (true, response: reply.response); 68 } 69 } 70 71 return (false, response: reply.response); 72 } 73 catch (Exception ex) 74 { 75 return (false, response: ex.Message); 76 } 77 } 78 79 private string GetSignUrl(Dictionary
parameters, string accessSecret) 80 { 81 var imutableMap = new Dictionary
(parameters); 82 imutableMap.Add("Timestamp", FormatIso8601Date(DateTime.Now)); 83 imutableMap.Add("SignatureMethod", "HMAC-SHA1"); 84 imutableMap.Add("SignatureVersion", "1.0"); 85 imutableMap.Add("SignatureNonce", Guid.NewGuid().ToString()); 86 imutableMap.Add("Action", Action); 87 imutableMap.Add("Version", Version); 88 imutableMap.Add("Format", Format); 89 imutableMap.Add("RegionId", RegionId); 90 91 IDictionary
sortedDictionary = new SortedDictionary
(imutableMap, StringComparer.Ordinal); 92 StringBuilder canonicalizedQueryString = new StringBuilder(); 93 foreach (var p in sortedDictionary) 94 { 95 canonicalizedQueryString.Append("&") 96 .Append(PercentEncode(p.Key)).Append("=") 97 .Append(PercentEncode(p.Value)); 98 } 99 100 StringBuilder stringToSign = new StringBuilder();101 stringToSign.Append("GET");102 stringToSign.Append(SEPARATOR);103 stringToSign.Append(PercentEncode("/"));104 stringToSign.Append(SEPARATOR);105 stringToSign.Append(PercentEncode(canonicalizedQueryString.ToString().Substring(1)));106 107 string signature = SignString(stringToSign.ToString(), accessSecret + "&");108 109 imutableMap.Add("Signature", signature);110 111 return ComposeUrl(Domain, imutableMap);112 }113 114 private static string FormatIso8601Date(DateTime date)115 {116 return date.ToUniversalTime().ToString("yyyy-MM-dd'T'HH:mm:ss'Z'", CultureInfo.CreateSpecificCulture("en-US"));117 }118 119 ///
120 /// 签名121 /// 122 public static string SignString(string source, string accessSecret)123 {124 using (var algorithm = new HMACSHA1(Encoding.UTF8.GetBytes(accessSecret.ToCharArray())))125 {126 return Convert.ToBase64String(algorithm.ComputeHash(Encoding.UTF8.GetBytes(source.ToCharArray())));127 }128 }129 130 private static string ComposeUrl(string endpoint, Dictionary
parameters)131 {132 StringBuilder urlBuilder = new StringBuilder("");133 urlBuilder.Append("http://").Append(endpoint);134 if (-1 == urlBuilder.ToString().IndexOf("?"))135 {136 urlBuilder.Append("/?");137 }138 string query = ConcatQueryString(parameters);139 return urlBuilder.Append(query).ToString();140 }141 142 private static string ConcatQueryString(Dictionary
parameters)143 {144 if (null == parameters)145 {146 return null;147 }148 StringBuilder sb = new StringBuilder();149 150 foreach (var entry in parameters)151 {152 String key = entry.Key;153 String val = entry.Value;154 155 sb.Append(HttpUtility.UrlEncode(key, Encoding.UTF8));156 if (val != null)157 {158 sb.Append("=").Append(HttpUtility.UrlEncode(val, Encoding.UTF8));159 }160 sb.Append("&");161 }162 163 int strIndex = sb.Length;164 if (parameters.Count > 0)165 sb.Remove(strIndex - 1, 1);166 167 return sb.ToString();168 }169 170 public static string PercentEncode(string value)171 {172 StringBuilder stringBuilder = new StringBuilder();173 string text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";174 byte[] bytes = Encoding.GetEncoding("UTF-8").GetBytes(value);175 foreach (char c in bytes)176 {177 if (text.IndexOf(c) >= 0)178 {179 stringBuilder.Append(c);180 }181 else182 {183 stringBuilder.Append("%").Append(184 string.Format(CultureInfo.InvariantCulture, "{0:X2}", (int)c));185 }186 }187 return stringBuilder.ToString();188 }189 190 private async Task<(int StatusCode, string response)> HttpGetAsync(string url)191 {192 HttpClientHandler handler = new HttpClientHandler();193 handler.Proxy = null;194 handler.AutomaticDecompression = DecompressionMethods.GZip;195 196 using (var http = new HttpClient(handler))197 {198 http.Timeout = new TimeSpan(TimeSpan.TicksPerMillisecond * TimeoutInMilliSeconds);199 HttpResponseMessage response = await http.GetAsync(url);200 return ((int)response.StatusCode, await response.Content.ReadAsStringAsync());201 }202 }203 }204 }

 

SmsObject.cs

1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4  5 namespace Vino.Core.Communication.SMS 6 { 7     public class SmsObject 8     { 9         /// 10         /// 手机号11         /// 12         public string Mobile { set; get; }13 14         /// 15         /// 签名16         /// 17         public string Signature { get; set; }18 19         /// 20         /// 模板Key21         /// 22         public string TempletKey { set; get; }23 24         /// 25         /// 短信数据26         /// 27         public IDictionary
Data { set; get; }28 29 ///
30 /// 业务ID31 /// 32 public string OutId { set; get; }33 }34 }

 

调用方法

1                         IDictionary
data = new Dictionary
(); 2 data.Add("code", "111111"); 3 var sms = new SmsObject 4 { 5 Mobile = "18812345678", 6 Signature = "我的签名", 7 TempletKey = "模板ID", 8 Data = data, 9 OutId = "OutId"10 };11 12 var res = await new AliyunSmsSender(accessKeyId, accessKeySecret).Send(sms);13 Debug.WriteLine($"发送结果:{res.success}");14 Debug.WriteLine($"Response:{res.response}");

 

转载于:https://www.cnblogs.com/kulend/p/8807716.html

你可能感兴趣的文章
percona-toolkit大表操作DDL使用
查看>>
【c++手记】Copy Constructor
查看>>
调用第三方物流公司API即时查询物流信息
查看>>
classifier in maven
查看>>
Jetson TX2介绍
查看>>
意见汇总
查看>>
【Golang 接口自动化07】struct转map的三种方式
查看>>
FPGA学习之串口组合
查看>>
Code Complete-13/7/23
查看>>
jmeter脚本中请求参数获取的几种方式
查看>>
java中的抽象类
查看>>
no.13如何通俗易懂理解区块链读后感
查看>>
C#基础拾遗系列之一:先看懂IL代码
查看>>
图上的文章(割点和桥)
查看>>
luogu1092虫食算(未AC,待续中~~~)
查看>>
Ghostscript 中 ps2pdf 命令在 windows msys 下的运行错误问题。
查看>>
cf 613E - Puzzle Lover
查看>>
SQL Server--导入和导出向导
查看>>
python 数据类型
查看>>
05-linux文件属性-硬链接-时间戳
查看>>