我只需要发个短信,没必要引入这么多dll吧。于是,根据阿里云官方文档,接口SDK源码,自己整理封装了一个类,完成发短信的操作。闲话不多说,直接上代码:
using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Net; using System.Security.Cryptography; using System.Text; namespace AliyunSMS { /// <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 = "***替换为自己的AccessKeyId***"; //用户标识 public static string AccessKeySecret = "***替换为自己的AccessKeySecret***"; //用户密钥 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="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; } } } }调用方式如下:(以发送短信验证码短信为例)
var random = new Random().Next(100000, 999999).ToString();
AliyunSmsHelper.SendSms("1******4902", "短信签名", "SMS_262******", "{\"code\":\"" + random + "\"}");
参考文档:
1.RPC调用机制:https://help.aliyun.com/document_detail/315526.htm?spm=a2c4g.11186623.0.0.46b027b5vlfd0X
2.发送短信文档: https://help.aliyun.com/document_detail/419273.htm?spm=a2c4g.11186623.0.0.34374198G2b44u
3.短信接口文档:https://help.aliyun.com/document_detail/419298.html?spm=5176.25163407.help.dexternal.774dbb6eylDOx0