.net core 借助容联云实现短信验证码
来源:互联网 发布:网站关键词优化智搜宝 编辑:程序博客网 时间:2024/05/22 08:15
官方网址:
http://www.yuntongxun.com/guide/sms.html
免费测试:
http://www.yuntongxun.com/doc/rest/sms/3_2_1_2.html
Demo实例
http://www.yuntongxun.com/doc/rest/sms/3_2_2_3.html
其实这个也不是很难,掉官方的sdk即可实现,但是苦逼的是我的项目是.net core ,官方的sdk有好多地方不支持,所以值得重写sdk
先把自己走过的坑补充一下:
出现的问题1:
l You must add a reference to assembly “mscorlib,Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”
解决办法:使用NuGet包管理安装:
Install-Package Microsoft.NETCore.Portable.Compatibility -Version 1.0.1
出现的问题2
l 对象引用对于非静态的字段,方法或属性
解决办法:
把出现问题的方法改成static即可
出现的问题3:
l 命名空间System.Net中不存在类型或者命名空间ServicePointManager
自己创建一个ServicePointManager,不要质疑,真的是照着原来的sdk创建了一个一模一样的方法就可以用了
出现的问题4:
WebHeaderCollection中的Headers未包含Add方法
这个其实是因为后来的WebHeaderCollection中的header可以这样添加:
类似的问题还有:
进行请求:
// 开始请求 using (Stream postStream = request.GetRequestStream()) { postStream.Write(byteData, 0, byteData.Length); }
在这里要换成:
var reqStreamAsync = request.GetRequestStreamAsync(); using(Stream reqStream = reqStreamAsync.Result) { reqStream.Write(byteData, 0, byteData.Length); reqStream.Dispose(); }
获取请求
// 获取请求 using (HttpWebResponse response = request.GetResponse() as HttpWebResponse) {
换成:
var reqAsync = request.GetResponseAsync(); using (HttpWebResponse response = reqAsync.Result as HttpWebResponse) {
下面的还有这种情况就不一一列举了,直接上sdk代码,需要的时候可以拿出来看看。
using System;using System.Collections.Generic;using System.IO;using System.Net;using System.Net.Http;using System.Net.Http.Headers;using System.Text;using System.Threading.Tasks;using System.Xml;namespace CCPRestSDK{ enum EBodyType : uint { EType_XML = 0, EType_JSON }; public class CCPRestSDK { private string m_restAddress = null; private string m_restPort = null; private string m_mainAccount = null; private string m_mainToken = null; private string m_appId = null; private EBodyType m_bodyType = EBodyType.EType_XML; /// <summary> /// 服务器api版本 /// </summary> const string softVer = "2013-12-26"; /// <summary> /// 初始化函数 /// </summary> /// <param name="serverIP">服务器地址</param> /// <param name="serverPort">服务器端口</param> /// <returns></returns> public bool init(string restAddress, string restPort) { this.m_restAddress = restAddress; this.m_restPort = restPort; if (m_restAddress == null || m_restAddress.Length < 0 || m_restPort == null || m_restPort.Length < 0 || Convert.ToInt32(m_restPort) < 0) return false; return true; } /// <summary> /// 设置主帐号信息 /// </summary> /// <param name="accountSid">主帐号</param> /// <param name="accountToken">主帐号令牌</param> public void setAccount(string accountSid, string accountToken) { this.m_mainAccount = accountSid; this.m_mainToken = accountToken; } /// <summary> /// 设置应用ID /// </summary> /// <param name="appId">应用ID</param> public void setAppId(string appId) { this.m_appId = appId; } /// <summary> /// 模板短信 /// </summary> /// <param name="to">短信接收端手机号码集合,用英文逗号分开,每批发送的手机号数量不得超过100个</param> /// <param name="templateId">模板Id</param> /// <param name="data">可选字段 内容数据,用于替换模板中{序号}</param> /// <exception cref="ArgumentNullException">参数不能为空</exception> /// <exception cref="Exception"></exception> /// <returns></returns> public Dictionary<string, object> SendTemplateSMS(string to, string templateId, string[] data) { Dictionary<string, object> initError = paramCheckRest(); if (initError != null) { return initError; } initError = paramCheckMainAccount(); if (initError != null) { return initError; } initError = paramCheckAppId(); if (initError != null) { return initError; } if (to == null) { throw new ArgumentNullException("to"); } if (templateId == null) { throw new ArgumentNullException("templateId"); } try { string date = DateTime.Now.ToString("yyyyMMddhhmmss"); // 构建URL内容 string sigstr = MD5Encrypt(m_mainAccount + m_mainToken + date); string uriStr = string.Format("https://{0}:{1}/{2}/Accounts/{3}/SMS/TemplateSMS?sig={4}", m_restAddress, m_restPort, softVer, m_mainAccount, sigstr); Uri address = new Uri(uriStr); Console.WriteLine("SendTemplateSMS url = " + uriStr); // 创建网络请求 HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest; setCertificateValidationCallBack(); // 构建Head request.Method = "POST"; Encoding myEncoding = Encoding.GetEncoding("utf-8"); byte[] myByte = myEncoding.GetBytes(m_mainAccount + ":" + date); string authStr = Convert.ToBase64String(myByte); request.Headers["Authorization"]= authStr; // 构建Body StringBuilder bodyData = new StringBuilder(); if (m_bodyType == EBodyType.EType_XML) { request.Accept = "application/xml"; request.ContentType = "application/xml;charset=utf-8"; bodyData.Append("<?xml version='1.0' encoding='utf-8'?><TemplateSMS>"); bodyData.Append("<to>").Append(to).Append("</to>"); bodyData.Append("<appId>").Append(m_appId).Append("</appId>"); bodyData.Append("<templateId>").Append(templateId).Append("</templateId>"); if (data != null && data.Length > 0) { bodyData.Append("<datas>"); foreach (string item in data) { bodyData.Append("<data>").Append(item).Append("</data>"); } bodyData.Append("</datas>"); } bodyData.Append("</TemplateSMS>"); } else { request.Accept = "application/json"; request.ContentType = "application/json;charset=utf-8"; bodyData.Append("{"); bodyData.Append("\"to\":\"").Append(to).Append("\""); bodyData.Append(",\"appId\":\"").Append(m_appId).Append("\""); bodyData.Append(",\"templateId\":\"").Append(templateId).Append("\""); if (data != null && data.Length > 0) { bodyData.Append(",\"datas\":["); int index = 0; foreach (string item in data) { if (index == 0) { bodyData.Append("\"" + item + "\""); } else { bodyData.Append(",\"" + item + "\""); } index++; } bodyData.Append("]"); } bodyData.Append("}"); } byte[] byteData = UTF8Encoding.UTF8.GetBytes(bodyData.ToString()); Console.WriteLine("SendTemplateSMS requestBody = " + bodyData.ToString()); // 开始请求 //using (Stream postStream = request.GetRequestStream()) //{ // postStream.Write(byteData, 0, byteData.Length); //} var reqStreamAsync = request.GetRequestStreamAsync(); using(Stream reqStream = reqStreamAsync.Result) { reqStream.Write(byteData, 0, byteData.Length); reqStream.Dispose(); } // 获取请求 var reqAsync = request.GetResponseAsync(); using (HttpWebResponse response = reqAsync.Result as HttpWebResponse) { // Get the response stream StreamReader reader = new StreamReader(response.GetResponseStream()); string responseStr = reader.ReadToEnd(); Console.WriteLine("SendTemplateSMS responseBody = " + responseStr); if (responseStr != null && responseStr.Length > 0) { Dictionary<string, object> responseResult = new Dictionary<string, object> { { "statusCode", "0" }, { "statusMsg", "成功" }, { "data", null } }; if (m_bodyType == EBodyType.EType_XML) { XmlDocument resultXml = new XmlDocument(); resultXml.LoadXml(responseStr); XmlNodeList nodeList = resultXml.GetElementsByTagName("Response"); foreach (XmlNode item in nodeList) { if (item.Name == "statusCode") { responseResult["statusCode"] = item.InnerText; } else if (item.Name == "statusMsg") { responseResult["statusMsg"] = item.InnerText; } else if (item.Name == "TemplateSMS") { Dictionary<string, object> retData = new Dictionary<string, object>(); foreach (XmlNode subItem in item.ChildNodes) { retData.Add(subItem.Name, subItem.InnerText); } responseResult["data"] = new Dictionary<string, object> { { item.Name, retData } }; } } } else { responseResult.Clear(); responseResult["resposeBody"] = responseStr; } return responseResult; } return new Dictionary<string, object> { { "statusCode", 172002 }, { "statusMsg", "无返回" }, { "data", null } }; } } catch (Exception e) { throw e; } } /// <summary> /// 检查服务器地址信息 /// </summary> /// <returns></returns> private Dictionary<string, object> paramCheckRest() { int statusCode = 0; string statusMsg = null; if (m_restAddress == null) { statusCode = 172004; statusMsg = "IP空"; } else if (m_restPort == null) { statusCode = 172005; statusMsg = "端口错误"; } if (statusCode != 0) { return new Dictionary<string, object> { { "statusCode", statusCode + "" }, { "statusMsg", statusMsg }, { "data", null } }; } return null; } /// <summary> /// 检查主帐号信息 /// </summary> /// <returns></returns> private Dictionary<string, object> paramCheckMainAccount() { int statusCode = 0; string statusMsg = null; if (m_mainAccount == null) { statusCode = 172006; statusMsg = "主帐号空"; } else if (m_mainToken == null) { statusCode = 172007; statusMsg = "主帐号令牌空"; } if (statusCode != 0) { return new Dictionary<string, object> { { "statusCode", statusCode + "" }, { "statusMsg", statusMsg }, { "data", null } }; } return null; } /// <summary> /// 检查应用ID /// </summary> /// <returns></returns> private Dictionary<string, object> paramCheckAppId() { if (m_appId == null) { return new Dictionary<string, object> { { "statusCode", 172012 + "" }, { "statusMsg", "应用ID为空" }, { "data", null } }; } return null; } /// <summary> /// MD5加密 /// </summary> /// <param name="source">原内容</param> /// <returns>加密后内容</returns> public static string MD5Encrypt(string source) { // Create a new instance of the MD5CryptoServiceProvider object. System.Security.Cryptography.MD5 md5Hasher = System.Security.Cryptography.MD5.Create(); // Convert the input string to a byte array and compute the hash. //--------------------------------------------------------------------------------Encoding.Default.GetBytes(source)-------------------------------------------------------- byte[] data = md5Hasher.ComputeHash(Encoding.ASCII.GetBytes(source)); // Create a new Stringbuilder to collect the bytes and create a string. StringBuilder sBuilder = new StringBuilder(); // Loop through each byte of the hashed data and format each one as a hexadecimal string. for (int i = 0; i < data.Length; i++) { sBuilder.Append(data[i].ToString("X2")); } // Return the hexadecimal string. return sBuilder.ToString(); } /// <summary> /// 设置服务器证书验证回调 /// </summary> public void setCertificateValidationCallBack() { System.Net.ServicePointManager.ServerCertificateValidationCallback = CertificateValidationResult; } /// <summary> /// 证书验证回调函数 /// </summary> /// <param name="obj"></param> /// <param name="cer"></param> /// <param name="chain"></param> /// <param name="error"></param> /// <returns></returns> public bool CertificateValidationResult(object obj, System.Security.Cryptography.X509Certificates.X509Certificate cer, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors error) { return true; } }}
using System.Net.Security;namespace System.Net{ public class ServicePointManager { public static RemoteCertificateValidationCallback ServerCertificateValidationCallback { get; set; } }}
而发送短信的调用sdk代码如下:
public static void SendSmSAsync() { string ret = null; CCPRestSDK.CCPRestSDK api = new CCPRestSDK.CCPRestSDK(); bool isInit = api.init("app.cloopen.com", "8883"); api.setAccount("8aaf07085e2d97fd015e454b503c07ab", "f7fac0ec2ae7468b8770a6e7d1db63b8"); api.setAppId("8aaf07085e2d97fd015e454b51c507b1"); try { if (isInit) { string[] data = { "7654", "10" };//验证码,时间 Dictionary<string, object> retData = api.SendTemplateSMS("13821875330", "1", data); ret = getDictionaryData(retData); string statusCode = retData["statusCode"].ToString(); string statusMsg = retData["statusMsg"].ToString(); Console.WriteLine(statusCode + "==" + statusMsg + "<br><br><br><br>"); } else { ret = "初始化失败"; } } catch (Exception exc) { ret = exc.Message; } finally { Console.Write(ret); } } public static string getDictionaryData(Dictionary<string, object> data) { string ret = null; foreach (KeyValuePair<string, object> item in data) { if (item.Value != null && item.Value.GetType() == typeof(Dictionary<string, object>)) { ret += item.Key.ToString() + "={"; ret += getDictionaryData((Dictionary<string, object>)item.Value); ret += "};"; } else { ret += item.Key.ToString() + "=" + (item.Value == null ? "null" : item.Value.ToString()) + ";"; } } return ret; }
最后在主函数中直接调用sendSms即可
项目的目录结构
实现效果
- .net core 借助容联云实现短信验证码
- .net core借助sendCloud实现邮件验证码发送
- .net 实现发送短信功能。(借助软信通彩信客户端)
- 实现短信验证码
- ASP.NET CORE 项目实战 ---图形验证码的实现
- ASP.NET MVC+Bootstrap 实现短信验证
- 借助短信平台实现手机注册页面的验证吗发送检验功能
- 短信验证码的实现
- PHP实现短信验证码
- java实现短信验证码
- java实现短信验证码
- 云片网实现短信验证码
- 短信验证码实现流程
- Nodejs实现短信验证码
- 云片网实现短信验证码
- java短信验证码实现
- Redis实现短信验证码
- Java实现短信验证码
- ZOJ 2136 Longest Ordered Subsequence(简单DP)
- java面试基础2
- Python:正则表达式(三)-re模块的内容
- js中生成json对象
- Day-01
- .net core 借助容联云实现短信验证码
- 51Nod-1832-先序遍历与后序遍历
- POJ1995 Raising Modulo Numbers(快速幂取模,模板题)
- 没有上司的舞会 树形DP 经典题目
- 一个错误
- 30. Substring with Concatenation of All Words
- windows下搭建virtualenv、virtualenvwrapper虚拟环境
- Codeforces Round #430-01字典树&类异或最大值-D. Vitya and Strange Lesson
- jQuery怎么获取<c:forEach>标签的值