C# ASP.NET MVC 阿里云短信验证码Demo

相信大家在开发过程中又很多使用到验证码验证的功能,今天将验证码的验证整理一下写了一个Demo

通过本篇后你能学习到:

  1. 阿里云短信服务
  2. Drapper连接SQL Server进行增改操作
  3. JS前端倒计时

完成后效果如下:

(一)首先我们要使用短信我们先注册短信服务所需的内容

1.首先阿里云短信验证码首先打开阿里云的短信服务网址

阿里云短信

2.进入管理控制台

在国内消息-签名模板中添加一个签名模板  签名模板名称这里要记一下后面的开发中需要填入

3.签名模板通过后我们需要再在国内消息模板管理里面添加一个短信模板   同样通过后  (模版CODE) 这个值在开发中需要填入

到这里我们短信发送所需的内容就已经注册好了接下来我们进行开发

(二)短信发送代码开发

1.我们首先用vs创建一个MVC的项目

2.使用nuget引用aliyun第三方类库如下图所示:

3.由于使用验证码需要通过数据库存储我这里使用了Drapper进行数据库操作,Drapper的操作我们后面单独用一篇文章来写

这里我就不详细写drapper引入的过程了

到这里我们所需的程序依赖就已经引入完毕了

4.我们首先需要编写一个发送短信的公共类来提供调用

阿里云这里提供了快速生成代码的网址可以通过该网站填入内容快速生产代码

代码快速生成

其中需要注意的一个地方就是TemplateParam这里我填的是

{"code":"你后台生生成的验证码"}

这里要和你申请的短信模板的内容相同比如你申请的是 ${code}

那么TemplateParam 就是  {"code":"你后台生成的验证码"}

如果申请的模板内容中带多个参数的话请带上多个json内容

将生产的代码改了改如下所示:

        static String product = "XXXX";//短信API产品名称static String domain = "dysmsapi.aliyuncs.com";//短信API产品域名static String accessId = "XXXX";static String accessSecret = "XXXX";static String regionIdForPop = "cn-hangzhou";//传入手机号和验证码public static CommonResponse SendMessage(string phone,string code){CommonResponse response = new CommonResponse();IClientProfile profile = DefaultProfile.GetProfile(regionIdForPop, accessId, accessSecret);DefaultAcsClient client = new DefaultAcsClient(profile);CommonRequest request = new CommonRequest();request.Method = MethodType.POST;request.Domain = domain;request.Version = "2017-05-25";request.Action = "SendSms";// request.Protocol = ProtocolType.HTTP;request.AddQueryParameters("PhoneNumbers", phone);request.AddQueryParameters("SignName", product);request.AddQueryParameters("TemplateCode", "xxxx");填入你模板管理中的模版CODErequest.AddQueryParameters("TemplateParam", "{\"code\":\"" + code + "\"}");//验证码try{response = client.GetCommonResponse(request);return response;}catch (ServerException e){Console.WriteLine(e);return response;}catch (ClientException e){Console.WriteLine(e);return response;}}

其中有一个accessId和accessSecret获取地址如下:

aceesid和accesssecret获取

完成封装过后开始前端和逻辑的处理

5.前端界面和代码如下:

@{ViewBag.Title = "短信发送";
}
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><meta http-equiv="Pragma" content="no-cache"><meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" /><meta name="format-detection" content="telephone=yes" /><meta name="apple-mobile-web-app-capable" content="yes" /><meta name="apple-mobile-web-app-status-bar-style" content="black" /><title>绑定信息</title><!-- Bootstrap core CSS--><!-- 最新版本的 Bootstrap 核心 CSS 文件 --><link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"><style type="text/css">body {margin: 0;padding: 0;}.modal_content {padding: 30px;display: flex;justify-content: center;flex-direction: column;}.modal_content > div {margin-bottom: 20px;}.modal_content > h5:first-child {margin: 30px 0px;}#dialog label {color: #666;}#phone {display: block;width: 100%;height: 70px;background: none;padding-top: 30px;border: 0;outline: none;text-align: center;margin-top: -30px;font-size: 16px;border-bottom: 1px solid rgba(0,0,0,.2);border-radius: 0;}.code {display: flex;flex-direction: row;justify-content: space-between;width: 100%;height: 70px;background: none;padding-top: 30px;margin-top: -30px;font-size: 16px;border-bottom: 1px solid rgba(0,0,0,.2);border-radius: 0;}#code {width: calc(100% - 90px);height: 55px;background: none;padding-top: 20px;border: 0;outline: none;text-align: center;margin-top: -20px;font-size: 16px;}#btnSendCode {width: 90px;height: 30px;padding: 0 5px;margin: 0;font-size: 14px;text-align: center;background: transparent;border-radius: 30px;color: #a07941;border-color: #a07941;}::-webkit-input-placeholder { /* WebKit browsers */font-size: 14px;color: rgba(0,0,0,.4);}:-moz-placeholder { /* Mozilla Firefox 4 to 18 */font-size: 14px;color: rgba(0,0,0,.4);}::-moz-placeholder { /* Mozilla Firefox 19+ */font-size: 14px;color: rgba(0,0,0,.4);}:-ms-input-placeholder { /* Internet Explorer 10+ */font-size: 14px;color: rgba(0,0,0,.4);}.next {text-align: center;margin: 20px 0;}.next button {width: 100%;height: 45px;padding: 0;margin: 0;background: #007BFF;color: #fff;border: 0;outline: none;border-radius: 3px;}</style>
</head>
<body><div class="modal_content"><h5>绑定用户信息!</h5><div><label for="phone">注册手机号:</label><br /><input id="phone" type="text" autocomplete="off" placeholder="请输入手机号" /></div><div><label for="code">验证码:</label><div class="code"><input id="code" type="text" autocomplete="off" placeholder="短信验证码" /><input id="btnSendCode" type="button" class="btn btn-default" value="获取验证码" onClick="sendMessage()" /></div></div><div class="next"><button onclick="binding()">确定</button></div></div><script src="http://www.jq22.com/jquery/jquery-1.10.2.js"></script><script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script><script>var phoneReg = /(^1[3|4|5|7|8]\d{9}$)|(^09\d{8}$)/;//手机号正则var count = 60; //间隔函数,1秒执行var InterValObj1; //timer变量,控制时间var curCount1;//当前剩余秒数/*第一*/function sendMessage() {curCount1 = count;var phone = $.trim($('#phone').val());if (!phoneReg.test(phone)) {alert(" 请输入有效的手机号码");return false;}//设置button效果,开始计时$("#btnSendCode").attr("disabled", "true");$("#btnSendCode").val(+ curCount1 + "秒再获取");InterValObj1 = window.setInterval(SetRemainTime1, 1000); //启动计时器,1秒执行一次//向后台发送处理数据var phone = $("#phone").val();$.ajax({type: "POST",url: '/Home/SendSms',data: { phone: phone },dataType: "json",success: function (data) {if (data.success != true || data.success != "true") {alert(data.Msg);}else {alert("发送成功");}},error: function (data) {alert(data.Msg);}});}function SetRemainTime1() {if (curCount1 == 0) {window.clearInterval(InterValObj1);//停止计时器$("#btnSendCode").removeAttr("disabled");//启用按钮$("#btnSendCode").val("重新发送");}else {curCount1--;$("#btnSendCode").val(+ curCount1 + "秒再获取");}}/*提交*/function binding() {var phone = $("#phone").val();var code = $("#code").val();$.ajax({type: "POST",url: '/Home/VlidateCode',data: { phone: phone, code: code },dataType: "json",success: function (data) {alert(data.Msg);},error: function (data) {alert(data.Msg);}});}</script>
</body>
</html>

6.后台代码:

(1)发送短信数据库如下所示

内容包含id,手机号,发送时间,是否失效,和验证码

(2)后台代码

发送短信前需要先查询发送短信时间是否过短

然后发送验证码成功后要将之前同一个手机发送过的验证码修改位失效状态

查询验证码的时候也得和验证码的有效时间一致过期了就提示重新发送短信

   /// <summary>/// 写入一条短信信息/// </summary>/// <param name="person">用户信息实体</param>/// <returns></returns>public bool Insert(Sms sms){using (IDbConnection db = new SqlConnection(DbHelper.ConnectionString)){string sql = "INSERT INTO Sms(phone, AddDate, Code) VALUES(@phone, @AddDate, @Code)";int result = db.Execute(sql, sms);return result > 0;  //简化的转换写法}}/// <summary>/// 根据手机号查询/// </summary>/// <param name="Phone">手机号</param>/// <returns></returns>public Sms FindByPhone(string Phone){using (IDbConnection db = new SqlConnection(DbHelper.ConnectionString)){DateTime Datimehours = DateTime.Now.AddMinutes(-30);string sql = $"SELECT * FROM Sms WHERE phone=@phone and IsDeleted=0 and adddate>@Datimehours";IEnumerable<Sms> list = db.Query<Sms>(sql, new { phone = Phone , Datimehours= Datimehours });return list.FirstOrDefault();}}/// <summary>/// 根据查询最近一次的手机号验证码判断是否大于60s用于判断是否发送时间间隔过短/// </summary>/// <param name="Phone">手机号</param>/// <returns></returns>public Boolean IsSoShort(string phone){Boolean SoShort = false;using (IDbConnection db = new SqlConnection(DbHelper.ConnectionString)){string sql = $"SELECT * FROM Sms WHERE phone=@phone";List<Sms> sms = db.Query<Sms>(sql, new { phone = phone }).OrderByDescending(t=>t.AddDate).ToList();//查询最近一次的手机号验证码//如果查询条数大于0if (sms.Count > 0){Sms LastSms = sms.FirstOrDefault();DateTime Now = DateTime.Now;DateTime SendTime = LastSms.AddDate;TimeSpan ts = Now.Subtract(SendTime);int sec = (int)ts.TotalSeconds;if (sec < 60){SoShort = true;}}return SoShort;}}/// <summary>/// 更新一条用户数据/// </summary>/// <param name="person">用户信息实体</param>/// <returns></returns>public bool Updatephone(string phone){using (IDbConnection db = new SqlConnection(DbHelper.ConnectionString)){string sql ="UPDATE Sms SET IsDeleted = 1  WHERE phone = @phone"; int result = db.Execute(sql, new { phone = phone });return result > 0;  //简化的转换写法}}

  public JsonResult SendSms(string phone){SendSmsResponse Smsresponse = new SendSmsResponse();SmsSendService sendserver = new SmsSendService();Boolean isshort = sendserver.IsSoShort(phone);if (isshort){return Json(new{success = false,Msg = "发送短信间隔过短请勿重复发送",data = ""});}//生成6位随机验证码string code = SendSmsHepler.Number(6);try{CommonResponse smsend = SendSmsHepler.SendMessage(phone, code);Smsresponse=JsonConvert.DeserializeObject<SendSmsResponse>(smsend.Data);}catch (Exception e){return Json(new{success = false,Msg = e.Message,data = ""});}//如果发送成功if (Smsresponse.Code != null && Smsresponse.Code == "OK"){Sms sms = new Sms();sms.phone = phone;sms.Code = code;sms.AddDate = DateTime.Now;//修改之前发送短信为失效状态bool upphone = sendserver.Updatephone(phone);//将新短信内容插入数据库var success = sendserver.Insert(sms);return Json(new{success = true,Msg = "成功",data = ""});}else{return Json(new{success = false,Msg = Smsresponse.Message,data = ""});}}public JsonResult VlidateCode(string phone,string code){SendSmsResponse Smsresponse = new SendSmsResponse();SmsSendService sendserver = new SmsSendService();Sms sms = sendserver.FindByPhone(phone);if (sms != null && sms.id>0){if (sms.Code == code){bool upphone = sendserver.Updatephone(phone);return Json(new{success = true,Msg = "验证成功",data = ""});}else{return Json(new{success = false,Msg = "验证失败",data = ""});}}else{return Json(new{success = false,Msg = "请先发送短信",data = ""});}}

最后需要源码都请扫码关注回复:短信Demo
下载地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/410367.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mybatis generator生成example_[Springboot系列] SpringBoot与Mybatis结合

本文作者&#xff1a;cuifuanMybatis 是一个持久层ORM框架&#xff0c;负责Java与数据库数据交互&#xff0c;也可以简易理解为中介&#xff0c;相对于它&#xff0c;还有个中介是hibernate,不过在mybatis中sql语句的灵活性&#xff0c;可优化性比较强&#xff0c;这也是现在大…

在laravel5.8中集成swoole组件----用协程实现的服务端和客户端(二)---静态文件如何部署...

目前&#xff0c;较为成熟的技术是采用laravelS组件&#xff0c;注意和laravel 区别laravelS多了一个大写的S&#xff0c;由于laravelS默认监听5200端口&#xff0c;所以laravel项目要做一些调整 例如&#xff1a; 静态文件引入的方式-----从静态资源服务器加载我们熟悉的js和c…

Linux上Oracle 11g安装步骤图解(超详细图文教程)附带导入数据和新建数据库教程

首先本文采用Docker方式快速在Linux上安装 目录 1.安装Docker容器 (1)登陆服务器&#xff0c;输入命令安装Docker容器 (2)安装完成后运行下列代码如果弹出Docker版本则表示安装成功 (3)启动Docker并设置跟随系统开机启动 (4)由于国内系统拉取国外镜像缓慢所以我们在开始安…

python中import sys_python import sys出错怎么办

当在pycharm中输入如下代码时&#xff1a;import sys 一、问题&#xff1a; sys下出现红色波浪线&#xff0c;按CtrlF1显示的信息为&#xff1a;no module named sys。 二、原因&#xff1a; 在装Python解释器时&#xff0c;我为了图方便装的是 Python 3.7.0a4 的embeddable版本…

Windows phone7 软件发布:理财计算器(包括wp7房贷计算器,wp7个税计算器,wp7存款利息计算器)...

前一段时间&#xff0c;需要经常用到贷款计算器的功能&#xff0c;这样有利于我们做出更好的决策。但是我们只能通过银行的工作人员的计算器来计算&#xff0c;给我带来了极大的不便和损失&#xff0c;由此便萌生了开发一个Windows phone7版的贷款计算器的功能。 此计算器目前的…

eclipse debug怎么用_利用maven/eclipse搭建ssm(spring+spring mvc+mybatis)

maven搭建安装过程挺简单的&#xff0c;去apache下载apache-maven的zip包&#xff0c;解压到一个目录下&#xff0c;如下图接下来配置windows环境&#xff0c;右击我的电脑--》属性--》高级系统设置--》环境变量--》系统变量--》新建&#xff0c;如下图就是你解压的maven的home…

【转载】ARM芯片介绍

ARM芯片介绍 作者&#xff1a;nbnb001 原文网址&#xff1a;http://bbs.imp3.net/thread-894970-1-1.html 一、ARM9系列 较小的核心面积带来较低的成本&#xff0c;相对比较省电&#xff0c;但难以冲击更高的频率&#xff0c;总体效能有限。 1. 威盛WM8505/WM8505 主频&#xf…

action请求是什么意思_凭什么说大疆Osmo Action可以干掉 GoPro hero7?

国内影像器材相关厂商中&#xff0c;大疆的研发实力显然处在第一阵营中的领军位置。这样评价它&#xff0c;不光是因为大疆这些年推出的产品在成像品质上都极为优秀&#xff0c;更是因为在爱好者眼中&#xff0c;这是一家“发起疯来连自家产品都打压”的技术疯子。和别人竞争&a…

数据共享如何改变世界_如何改变他人?“我不会去改变这个世界,我们会去改变自己”。...

我们每一个人都经常觉得&#xff0c;如果要是别人改变了的话&#xff0c;我们就会变得快乐&#xff0c;如果别人会做这一点的话&#xff0c;我就会变成快乐。我们就是一直不断地去努力&#xff0c;而且也希望别人可以改变。我见到很多的人&#xff0c;来参加我们的课程&#xf…

在laravel5.8中集成swoole组件----用协程实现的服务端和客户端(nginx配置篇章)

laravel项目中的配置 原文出处&#xff1a;https://laravelacademy.org/post/19700.html&#xff0c;感谢原文作者让laravel这款可爱的php框架&#xff0c;进入了高并发的殿堂如果你已经成功安装了laravelS组件&#xff0c;并用他接管了你的laravel项目&#xff0c;那么接下来…

编程之美-2.17-数组循环移位

1. 简述 设计一个算法&#xff0c;把一个含有N个元素的数组循环右移K位&#xff0c;要求时间复杂度为O(N)&#xff0c;且只允许使用两个附加变量。 2. 思路 其实看到题目中只允许两个附加变量应该也能想到&#xff0c;就是两个变量倒来倒去就行了。如果熟悉希尔排序的话&#x…

Rails 3:提高Ajax应用速度

Rails 3&#xff1a;提高Ajax应用速度 http://developer.51cto.com 2011-05-18 09:45 Stefan Siebel 51CTO 我要评论(0)我建立了一个列表网站&#xff0c;ListKungFo&#xff0c;其中大量使用了Ajax&#xff0c;目前为止网站运行非常良好。而过去两周里&#xff0c;我一直在…

opencv支持python3吗_Python3.4+opencv3

1、安装Python 3.4 for Windows 好的这好像没有什么可以说的 2、下载OpenCV 3和Numpy(OpenCV依赖Numpy库) 大家在这里就出了问题。如果使用直接使用pip install pyopencv安装一定会出错。这里使用了Python界活雷锋封装的安装包&#xff0c;大家根据自己的系统下载&#xff1a; …

cacti安装配置详解_MySQL实战001:8.0免安装版服务配置详解

首先我们需要先下载MySQL的安装包&#xff0c;MYSQL官方下载地址&#xff1a;https://dev.mysql.com/downloads/mysql/&#xff0c;这里我下载的是MySQL Community Server 8.0.15版本&#xff0c;以前MySQL还有安装版&#xff0c;现在都是压缩版&#xff0c;解压之后将环境配置…

laydate时间控件有时候无效_新角度,如何无效没用地听课

嗨喽&#xff0c;大家好。这一期我想向大家展示一下如何无效地听课。1.上课的时候&#xff0c;全程集中注意力&#xff0c;每一秒都不能放松&#xff0c;使自己的大脑保持高度紧张中。我们这么年轻&#xff0c;精神充沛得很&#xff0c;只要累不死就往死里学。 2.下课的时候也不…

anaconda python删除pyltp_Anaconda使用

Anaconda 是什么&#xff1f;Anaconda 是一个可用于科学计算的 Python 发行版&#xff0c;支持 Linux、Mac、 Windows系统&#xff0c;内置了常用的科学计算包。它解决了官方 Python 的两大痛点。第一&#xff1a;提供了包管理功能&#xff0c;Windows 平台安装第三方包经常失败…

gc日志怎么看_你应该怎么监控Kafka?

监控 Kafka&#xff0c;历来都是个老大难的问题。无论是在我维护的微信公众号&#xff0c;还是 Kafka QQ群里面&#xff0c;大家问得最多的问题&#xff0c;一定是 Kafka 的监控。大家提问的内容看似五花八门&#xff0c;但真正想了解的&#xff0c;其实都是监控这点事&#xf…

c语言 二进制输出_收藏!C语言入门基础知识大全

C语言中的逻辑值只有两个&#xff1a;真(true)和假(flase)。用非零代表真&#xff0c;用零代表假。因此&#xff0c;对于任意一个表达式&#xff0c;如果它的值为零&#xff0c;就代表一个假值&#xff0c;如果它的值为非零&#xff0c;就代表一个真值。只要值不是零&#xff0…

机器学习算法与Python实践之(七)逻辑回归(Logistic Regression)

http://blog.csdn.net/zouxy09/article/details/20319673 机器学习算法与Python实践之&#xff08;七&#xff09;逻辑回归&#xff08;Logistic Regression&#xff09; zouxy09qq.com http://blog.csdn.net/zouxy09 机器学习算法与Python实践这个系列主要是参考《机器学习实战…

protected访问权限_复习封装与访问控制

java 中的封装性是通过对成员变量和方法进行访问控制实现的&#xff0c;访问控制分为个等级 &#xff1a;私有 private &#xff1b;默认 &#xff1b;保护 protected &#xff1b;公有 public &#xff1b;访问权限表控制等级 同一个类 同一个包 不同包的子包 不同包非子类 私…