C#
样例 |
|
---|---|
环境要求 |
.net 7.0,Visual Studio Code 1.75.1(插件C# v1.25.7, Code Runner v0.12.0(非必选)) |
- 发送短信为单模板群发短信示例,发送分批短信为多模板群发短信示例。
- 本文档所述Demo在提供服务的过程中,可能会涉及个人数据的使用,建议您遵从国家的相关法律采取足够的措施,以确保用户的个人数据受到充分的保护。
- 本文档所述Demo仅用于功能演示,不允许客户直接进行商业使用。
- 本文档信息仅供参考,不构成任何要约或承诺。
参考API签名SDK与demo,点击下载其中的SDK与Demo。以Visual Studio Code为例,在本地资源管理器选择一个目录,比如D:/sms,使用终端进入。
- 执行dotnet new console命令,产生一个工程。
- 将Signer.cs、HttpEncoder.cs复制到D:/sms文件夹;然后在sms文件夹内新建SendSms.cs空文件,再将下列样例(比如“发送短信示例”)的内容复制到SendSms.cs中。
- 用Visual Studio Code打开该工程,即可运行SendSms.cs。
发送短信示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
using System; using System.Net; using System.IO; using APIGATEWAY_SDK; using System.Text; namespace DEMO { class Program { static void Main(string[] args) { ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; //必填,请参考"开发准备"获取如下数据,替换为实际值 string apiAddress = "https://smsapi.cn-north-4.myhuaweicloud.com:443/sms/batchSendSms/v1"; //APP接入地址(在控制台"应用管理"页面获取)+接口访问URI // 认证用的appKey和appSecret硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全; string appKey = "c8RWg3ggEcyd4D3p94bf3Y7x1Ile"; //APP_Key string appSecret = "q4Ii87Bh************80SfD7Al"; //APP_Secret string sender = "csms12345678"; //国内短信签名通道号 string templateId = "8ff55eac1d0b478ab3c06c3c6a492300"; //模板ID //条件必填,国内短信关注,当templateId指定的模板类型为通用模板时生效且必填,必须是已审核通过的,与模板类型一致的签名名称 //string signature = "华为云短信测试"; //签名名称 //必填,全局号码格式(包含国家码),示例:+86151****6789,多个号码之间用英文逗号分隔 string receiver = "+86137****6781,+86137****6782"; //短信接收人号码 //选填,短信状态报告接收地址,推荐使用域名,为空或者不填表示不接收状态报告 string statusCallBack = ""; /* * 选填,使用无变量模板时请赋空值 string templateParas = ""; * 单变量模板示例:模板内容为"您的验证码是${1}"时,templateParas可填写为"[\"369751\"]" * 双变量模板示例:模板内容为"您有${1}件快递请到${2}领取"时,templateParas可填写为"[\"3\",\"人民公园正门\"]" * 模板中的每个变量都必须赋值,且取值不能为空 * 查看更多模板规范和变量规范:产品介绍>短信模板须知和短信变量须知 */ string templateParas = "[\"369751\"]"; //模板变量,此处以单变量验证码短信为例,请客户自行生成6位验证码,并定义为字符串类型,以杜绝首位0丢失的问题(例如:002569变成了2569)。 Signer signer = new Signer(); signer.Key = appKey; signer.Secret = appSecret; HttpRequest r = new HttpRequest("POST", new Uri(apiAddress)); //APP接入地址(在控制台"应用管理"页面获取)+接口访问URI //请求Body var body = new Dictionary<string, string>() { {"from", sender}, {"to", receiver}, {"templateId", templateId}, {"templateParas", templateParas}, {"statusCallback", statusCallBack}, //{"signature", signature} //使用国内短信通用模板时,必须填写签名名称 }; r.body =new FormUrlEncodedContent(body).ReadAsStringAsync().Result; r.headers.Add("Content-Type", "application/x-www-form-urlencoded"); HttpWebRequest req = signer.Sign(r); Console.WriteLine(req.Headers.GetValues("x-sdk-date")[0]); Console.WriteLine(string.Join(", ", req.Headers.GetValues("authorization"))); Console.WriteLine("body: " + r.body); // 不校验证书 ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true; try { var writer = new StreamWriter(req.GetRequestStream()); writer.Write(r.body); writer.Flush(); HttpWebResponse resp = (HttpWebResponse)req.GetResponse(); var reader = new StreamReader(resp.GetResponseStream()); Console.WriteLine(reader.ReadToEnd()); } catch (WebException e) { HttpWebResponse resp = (HttpWebResponse)e.Response; if (resp != null) { Console.WriteLine((int)resp.StatusCode + " " + resp.StatusDescription); var reader = new StreamReader(resp.GetResponseStream()); Console.WriteLine(reader.ReadToEnd()); } else { Console.WriteLine(e.Message); } } } } } |
发送分批短信示例
引用库:Newtonsoft.Json 11.0.2及以上版本,请参考https://www.newtonsoft.com/json获取。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
using System; using System.Net; using System.IO; using APIGATEWAY_SDK; using System.Text; using System.Collections; using System.Collections.Generic; using Newtonsoft.Json; namespace DEMODiffSMS { class Program { static void Main(string[] args) { ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; //必填,请参考"开发准备"获取如下数据,替换为实际值 string apiAddress = "https://smsapi.cn-north-4.myhuaweicloud.com:443/sms/batchSendDiffSms/v1"; //APP接入地址(在控制台"应用管理"页面获取)+接口访问URI // 认证用的appKey和appSecret硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全; string appKey = "c8RWg3ggEcyd4D3p94bf3Y7x1Ile"; //APP_Key string appSecret = "q4Ii87Bh************80SfD7Al"; //APP_Secret string sender = "csms12345678"; //国内短信签名通道号 string templateId_1 = "8ff55eac1d0b478ab3c06c3c6a492300"; //模板ID1 string templateId_2 = "8ff55eac1d0b478ab3c06c3c6a492301"; //模板ID2 //条件必填,国内短信关注,当templateId指定的模板类型为通用模板时生效且必填,必须是已审核通过的,与模板类型一致的签名名称 string signature_1 = "华为云短信测试1"; //签名名称1 string signature_2 = "华为云短信测试2"; //签名名称2 //必填,全局号码格式(包含国家码),示例:+86151****6789,多个号码之间用英文逗号分隔 string[] receiver_1 = { "+86151****6781", "+86151****6783" }; //模板1的接收号码 string[] receiver_2 = { "+86151****6782", "+86151****6784" }; //模板2的接收号码 //选填,短信状态报告接收地址,推荐使用域名,为空或者不填表示不接收状态报告 string statusCallBack = "https://your.server.com/rest/callback/statusReport"; /* * 选填,使用无变量模板时请赋空值 string[] templateParas = {}; * 单变量模板示例:模板内容为"您的验证码是${1}"时,templateParas可填写为{"369751"} * 双变量模板示例:模板内容为"您有${1}件快递请到${2}领取"时,templateParas可填写为{"3","人民公园正门"} * 模板中的每个变量都必须赋值,且取值不能为空 * 查看更多模板规范和变量规范:产品介绍>短信模板须知和短信变量须知 */ string[] templateParas_1 = {"123456"}; //模板1变量,此处以单变量验证码短信为例,请客户自行生成6位验证码,并定义为字符串类型,以杜绝首位0丢失的问题(例如:002569变成了2569)。 string[] templateParas_2 = {"234567"}; //模板2变量,此处以单变量验证码短信为例,请客户自行生成6位验证码,并定义为字符串类型,以杜绝首位0丢失的问题(例如:002569变成了2569)。 ArrayList smsContent = new ArrayList { //smsContent,不携带签名名称时,signature请填null InitDiffSms(receiver_1, templateId_1, templateParas_1, signature_1), InitDiffSms(receiver_2, templateId_2, templateParas_2, signature_2) }; //请求Body var body = new Dictionary<string, object>{ {"from", sender}, {"statusCallback", statusCallBack}, {"smsContent", smsContent} }; Signer signer = new Signer(); signer.Key = appKey; signer.Secret = appSecret; HttpRequest r = new HttpRequest("POST", new Uri(apiAddress)); r.body = JsonConvert.SerializeObject(body); r.headers.Add("Content-Type", "application/json"); HttpWebRequest req = signer.Sign(r); Console.WriteLine(req.Headers.GetValues("x-sdk-date")[0]); Console.WriteLine(string.Join(", ", req.Headers.GetValues("authorization"))); Console.WriteLine("body: " + r.body); // 不校验证书 ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true; try { var writer = new StreamWriter(req.GetRequestStream()); writer.Write(r.body); writer.Flush(); HttpWebResponse resp = (HttpWebResponse)req.GetResponse(); var reader = new StreamReader(resp.GetResponseStream()); Console.WriteLine(reader.ReadToEnd()); } catch (WebException e) { HttpWebResponse resp = (HttpWebResponse)e.Response; if (resp != null) { Console.WriteLine((int)resp.StatusCode + " " + resp.StatusDescription); var reader = new StreamReader(resp.GetResponseStream()); Console.WriteLine(reader.ReadToEnd()); } else { Console.WriteLine(e.Message); } } } static Dictionary<string, object> InitDiffSms(string[] receiver, string templateId, string[] templateParas, string signature) { Dictionary<string, object> dic = new Dictionary<string, object> { {"to", receiver}, {"templateId", templateId}, {"templateParas", templateParas} }; if (!signature.Equals(null) && signature.Length > 0) { dic.Add("signature", signature); } return dic; } } } |
接收状态报告
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
using System; using System.Web; namespace msgsms_csharp_demo { class Report { static void Main(string[] args) { //string success_body = "sequence=1&total=1&updateTime=2018-10-31T08%3A43%3A41Z&source=2&smsMsgId=2ea20735-f856-4376-afbf-570bd70a46ee_11840135&status=DELIVRD"; string failed_body = "sequence=1&total=1&updateTime=2018-10-31T08%3A43%3A41Z&source=2&smsMsgId=2ea20735-f856-4376-afbf-570bd70a46ee_11840135&status=E200027"; //OnSmsStatusReport(success_body); OnSmsStatusReport(failed_body); } /// <summary> /// 解析状态报告数据 /// </summary> /// <param name="data">短信平台上报的状态报告数据</param> static void OnSmsStatusReport(string data) { var keyValues = HttpUtility.ParseQueryString(data); //解析状态报告数据 /** * Example: 此处已解析status为例,请按需解析所需参数并自行实现相关处理 * * 'smsMsgId': 短信唯一标识 * 'total': 长短信拆分条数 * 'sequence': 拆分后短信序号 * 'source': 状态报告来源 * 'updateTime': 资源更新时间 * 'status': 状态码 */ string status = keyValues.Get("status"); // 状态报告枚举值 // 通过status判断短信是否发送成功 if ("DELIVRD".Equals(status.ToUpper())) { Console.WriteLine("Send sms success. smsMsgId: " + keyValues.Get("smsMsgId")); } else { // 发送失败,打印status和orgCode Console.WriteLine("Send sms failed. smsMsgId: " + keyValues.Get("smsMsgId")); Console.WriteLine("Failed status: " + status); } } } } |
接收上行短信
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
using System; using System.Web; namespace msgsms_csharp_demo { class UpData { static void Main(string[] args) { string updata = "from=%2B86151****6789&to=1069****019&body=********&smsMsgId=9692b5be-c427-4525-8e73-cf4a6ac5b3f7"; onSmsUpData(updata); } /// <summary> /// 解析上行短信通知数据 /// </summary> /// <param name="data">短信平台推送的上行短信通知数据</param> static void onSmsUpData(string data) { var keyValues = HttpUtility.ParseQueryString(data); //解析上行短信通知数据 /** * Example: 此处已解析body为例,请按需解析所需参数并自行实现相关处理 * * 'smsMsgId': 上行短信唯一标识 * 'from': 上行短信发送方的号码 * 'to': 上行短信接收方的号码 * 'body': 上行短信发送的内容 */ string body = keyValues.Get("body"); // 上行短信发送的内容 Console.WriteLine("Sms up data. Body: " + body); } } } |