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

 using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Web; namespace Vino.Core.Communication.SMS
{
public class AliyunSmsSender : ISmsSender
{
private string RegionId = "cn-hangzhou";
private string Version = "2017-05-25";
private string Action = "SendSms";
private string Format = "JSON";
private string Domain = "dysmsapi.aliyuncs.com"; private int MaxRetryNumber = ;
private bool AutoRetry = true;
private const string SEPARATOR = "&";
private int TimeoutInMilliSeconds = ; private string AccessKeyId;
private string AccessKeySecret; public AliyunSmsSender(string accessKeyId, string accessKeySecret)
{
this.AccessKeyId = accessKeyId;
this.AccessKeySecret = accessKeySecret;
} /// <summary>
/// 发送短信
/// </summary>
public async Task<(bool success, string response)> Send(SmsObject sms)
{
var paramers = new Dictionary<string, string>();
paramers.Add("PhoneNumbers", sms.Mobile);
paramers.Add("SignName", sms.Signature);
paramers.Add("TemplateCode", sms.TempletKey);
paramers.Add("TemplateParam", JsonConvert.SerializeObject(sms.Data));
paramers.Add("OutId", sms.OutId);
paramers.Add("AccessKeyId", AccessKeyId); try
{
string url = GetSignUrl(paramers, AccessKeySecret); int retryTimes = ;
var reply = await HttpGetAsync(url);
while ( <= reply.StatusCode && AutoRetry && retryTimes < MaxRetryNumber)
{
url = GetSignUrl(paramers, AccessKeySecret);
reply = await HttpGetAsync(url);
retryTimes++;
} if (!string.IsNullOrEmpty(reply.response))
{
var res = JsonConvert.DeserializeObject<Dictionary<string, string>>(reply.response);
if (res != null && res.ContainsKey("Code") && "OK".Equals(res["Code"]))
{
return (true, response: reply.response);
}
} return (false, response: reply.response);
}
catch (Exception ex)
{
return (false, response: ex.Message);
}
} private string GetSignUrl(Dictionary<string, string> parameters, string accessSecret)
{
var imutableMap = new Dictionary<string, string>(parameters);
imutableMap.Add("Timestamp", FormatIso8601Date(DateTime.Now));
imutableMap.Add("SignatureMethod", "HMAC-SHA1");
imutableMap.Add("SignatureVersion", "1.0");
imutableMap.Add("SignatureNonce", Guid.NewGuid().ToString());
imutableMap.Add("Action", Action);
imutableMap.Add("Version", Version);
imutableMap.Add("Format", Format);
imutableMap.Add("RegionId", RegionId); IDictionary<string, string> sortedDictionary = new SortedDictionary<string, string>(imutableMap, StringComparer.Ordinal);
StringBuilder canonicalizedQueryString = new StringBuilder();
foreach (var p in sortedDictionary)
{
canonicalizedQueryString.Append("&")
.Append(PercentEncode(p.Key)).Append("=")
.Append(PercentEncode(p.Value));
} StringBuilder stringToSign = new StringBuilder();
stringToSign.Append("GET");
stringToSign.Append(SEPARATOR);
stringToSign.Append(PercentEncode("/"));
stringToSign.Append(SEPARATOR);
stringToSign.Append(PercentEncode(canonicalizedQueryString.ToString().Substring())); string signature = SignString(stringToSign.ToString(), accessSecret + "&"); imutableMap.Add("Signature", signature); return ComposeUrl(Domain, imutableMap);
} private static string FormatIso8601Date(DateTime date)
{
return date.ToUniversalTime().ToString("yyyy-MM-dd'T'HH:mm:ss'Z'", CultureInfo.CreateSpecificCulture("en-US"));
} /// <summary>
/// 签名
/// </summary>
public static string SignString(string source, string accessSecret)
{
using (var algorithm = new HMACSHA1(Encoding.UTF8.GetBytes(accessSecret.ToCharArray())))
{
return Convert.ToBase64String(algorithm.ComputeHash(Encoding.UTF8.GetBytes(source.ToCharArray())));
}
} private static string ComposeUrl(string endpoint, Dictionary<String, String> parameters)
{
StringBuilder urlBuilder = new StringBuilder("");
urlBuilder.Append("http://").Append(endpoint);
if (- == urlBuilder.ToString().IndexOf("?"))
{
urlBuilder.Append("/?");
}
string query = ConcatQueryString(parameters);
return urlBuilder.Append(query).ToString();
} private static string ConcatQueryString(Dictionary<string, string> parameters)
{
if (null == parameters)
{
return null;
}
StringBuilder sb = new StringBuilder(); foreach (var entry in parameters)
{
String key = entry.Key;
String val = entry.Value; sb.Append(HttpUtility.UrlEncode(key, Encoding.UTF8));
if (val != null)
{
sb.Append("=").Append(HttpUtility.UrlEncode(val, Encoding.UTF8));
}
sb.Append("&");
} int strIndex = sb.Length;
if (parameters.Count > )
sb.Remove(strIndex - , ); return sb.ToString();
} public static string PercentEncode(string value)
{
StringBuilder stringBuilder = new StringBuilder();
string text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";
byte[] bytes = Encoding.GetEncoding("UTF-8").GetBytes(value);
foreach (char c in bytes)
{
if (text.IndexOf(c) >= )
{
stringBuilder.Append(c);
}
else
{
stringBuilder.Append("%").Append(
string.Format(CultureInfo.InvariantCulture, "{0:X2}", (int)c));
}
}
return stringBuilder.ToString();
} private async Task<(int StatusCode, string response)> HttpGetAsync(string url)
{
HttpClientHandler handler = new HttpClientHandler();
handler.Proxy = null;
handler.AutomaticDecompression = DecompressionMethods.GZip; using (var http = new HttpClient(handler))
{
http.Timeout = new TimeSpan(TimeSpan.TicksPerMillisecond * TimeoutInMilliSeconds);
HttpResponseMessage response = await http.GetAsync(url);
return ((int)response.StatusCode, await response.Content.ReadAsStringAsync());
}
}
}
}

SmsObject.cs

 using System;
using System.Collections.Generic;
using System.Text; namespace Vino.Core.Communication.SMS
{
public class SmsObject
{
/// <summary>
/// 手机号
/// </summary>
public string Mobile { set; get; } /// <summary>
/// 签名
/// </summary>
public string Signature { get; set; } /// <summary>
/// 模板Key
/// </summary>
public string TempletKey { set; get; } /// <summary>
/// 短信数据
/// </summary>
public IDictionary<string, string> Data { set; get; } /// <summary>
/// 业务ID
/// </summary>
public string OutId { set; get; }
}
}

调用方法

                         IDictionary<string, string> data = new Dictionary<string, string>();
data.Add("code", "");
var sms = new SmsObject
{
Mobile = "",
Signature = "我的签名",
TempletKey = "模板ID",
Data = data,
OutId = "OutId"
}; var res = await new AliyunSmsSender(accessKeyId, accessKeySecret).Send(sms);
Debug.WriteLine($"发送结果:{res.success}");
Debug.WriteLine($"Response:{res.response}");

.net core 使用阿里云短信发送SMS的更多相关文章

  1. Abp 添加阿里云短信发送

    ABP中有短信发送接口ISmsSender public interface ISmsSender { Task<string> SendAsync(string number, stri ...

  2. 2018阿里云短信发送DEMO接入简单实例

    以下更新2018-04-2309:57:54 后续不再更新, 基本类: app/SignatureHelper.php <?php namespace aliyun_mns; /** * 签名助 ...

  3. 阿里云短信发送服务SDK-Python3

    本文提供阿里云的短信发送服务SDK,使用Python3实现. # -*- coding: utf-8 -*- # pip install requests import requests import ...

  4. spring boot集成阿里云短信发送接收短信回复功能

    1.集成阿里云通信发送短信: 在pom.xml文件里添加依赖 <!--阿里短信服务--> <dependency> <groupId>com.aliyun</ ...

  5. tp5阿里云短信发送

    到阿里云下载php版demo,下完整版的,不是轻量级的; 框架  :TP5 把下载下来的文件放到extend里面 文件名:alimsg 里面的文件 import('alimsg.api_demo.Sm ...

  6. java 阿里云短信发送

    记录自己的足迹,学习的路很长,一直在走着呢~ 第一步登录阿里云的控制台,找到此处: 点击之后就到此页面,如果发现账号有异常或者泄露什么,可以禁用或者删除  AccessKey: 此处方便测试,所以就新 ...

  7. ABP框架中短信发送处理,包括阿里云短信和普通短信商的短信发送集成

    在一般的系统中,往往也有短信模块的需求,如动态密码的登录,系统密码的找回,以及为了获取用户手机号码的短信确认等等,在ABP框架中,本身提供了对邮件.短信的基础支持,那么只需要根据自己的情况实现对应的接 ...

  8. 阿里云短信服务开发报错Java.lang.NoClassDefFoundError:com/aliyuncs/exceptions/ClientException

    手机app获取短信验证码功能时候,遇到的问题.使用的是阿里云的短信服务,下载平台demo时运行不报错,但是在service层调用的时候报错 Java.lang.NoClassDefFoundError ...

  9. 阿里云短信验证解决方案(java版)(redis存储)

    最近搞了一个互联网项目的注册,需要写一个手机号验证(由于之前没有轮子,只能自己摸索了); 1:基本思路: 1>购买了阿里云短信服务->下载阿里云短信发送demo(java版); 2> ...

随机推荐

  1. 用C#语言编写:集合管理器

    static void Main(string[] args)        {            List<int> numbers = new List<int>(); ...

  2. Java 容器 接口

    Java 中容器框架的内容可以分为三层: 接口(模型), 模板和具体实现. 在开发中使用容器正常的流程是,首先根据需求确定使用何种容器模型,然后选择一个符合性能要求的容器实现类或者自己实现一个容器类. ...

  3. java大数(BigInteger)

    JAVA之BigInteger 用Java来处理高精度问题,相信对很多ACMer来说都是一件很happy的事,简单易懂.用Java刷了一些题,感觉Java还不错,在处理高精度和进制转换中,调用库函数的 ...

  4. 将 Shiro 作为应用的权限基础 三:基于注解实现的授权认证过程

    授权即访问控制,它将判断用户在应用程序中对资源是否拥有相应的访问权限. 如,判断一个用户有查看页面的权限,编辑数据的权限,拥有某一按钮的权限等等. 一.用户权限模型 为实现一个较为灵活的用户权限数据模 ...

  5. JAVA连接SAP

    1.首先需要在SAP事务码SE37中新建一个可以被远程调用的RFC 事务码:SE37 新建一个函数组:输入事务码SE37回车后,来到函数构建器屏幕,到上面一排菜单栏:转到 -> 函数组 -> ...

  6. linux小白成长之路8————访问Docker中的mysql

    [内容指引] 本篇实战演示如何操作Docker中的mysql数据库,包含以下五个知识点: 登录容器: 登录mysql: 运行SQL指令创建数据库: 退出mysql: 退出容器: 1.登录容器 我们在上 ...

  7. <经验杂谈>C#使用AES加密解密的简单介绍

    AES 算法是基于置换和代替的.置换是数据的重新排列,而代替是用一个单元数据替换另一个.AES 使用了几种不同的技术来实现置换和替换. 以下是我自己用c#研究出来算法Code: /// <sum ...

  8. java多线程的(一)-之java线程的使用

    一.摘要 每天都和电脑打交道,也相信大家使用过资源管理器杀掉过进程.而windows本身就是多进程的操作系统 在这里我们理解两组基本概念: 1.进程和线程的区别???? 2.并行与并发的区别???? ...

  9. JaveScript对象(JS知识点归纳七)

    1.JS中的对象表示的是一个具体的事物. a)静态的特征=>对象的属性 b)动态的行为=>对象的方法=>保存的值==>函数 2.对象的创建方式 a)构造函数的创建方式 ``` ...

  10. 解决办法:由于oracle版本不同导致导入数据时失败

    在向一个数据库导入dmp文件时,出现了如下错误 经查询,是由于"导出的dmp文件与导入的数据库的版本不同造成的" 用notepad查看dmp文件的版本,看看是否和数据库版本一致 解 ...