前言
Asp.net的发展与作用
发展
ASP.NET的发展历程经历了多个重要阶段:
- 1.2000年,ASP.NET 1.0正式发布,标志着ASP.NET技术的诞生。
- 2003年,ASP.NET升级为1.1版本,进一步激发了Web应用程序开发人员对ASP.NET的兴趣,并对网络技术产生了巨大的推动作用。
- 2005年11月,微软发布了ASP.NET 2.0,这是.NET技术走向成熟的标志。ASP.NET 2.0增加了许多方便、实用的新特性,使Web开发人员能够更加快捷方便地开发Web应用程序。
- 随后,微软推出了ASP.NET 3.5版本,使网络程序开发更倾向于智能开发,运行起来更加流畅。
- 此外,微软还推出了ASP.NET MVC框架,采用了分层架构,提高了代码的可维护性和可扩展性。
- 2.ASP.NET Web API的发展也经历了多个版本:
- 早期版本提供了基本的API创建和管理功能。
- 随着版本的升级,ASP.NET Web API增加了许多新特性,如在线文档的自动字段注释功能、对JSON和XML等数据格式的支持等。
- 目前,ASP.NET Web API已经成为构建Web服务和API的重要工具之一,广泛应用于各种Web应用程序中。
作用
- 提供业务逻辑访问:Web API作为业务逻辑提供方,承载了项目的核心逻辑。通过定义接口和控制器,开发者可以轻松地实现业务逻辑的封装和访问。
- 数据交换:Web API支持多种数据格式(如JSON、XML等),使得客户端和服务器之间的数据交换变得简单和高效。
- 跨平台支持:由于Web API基于HTTP协议,因此它可以被任何支持HTTP的客户端访问,包括浏览器、移动应用、桌面应用等。
- 安全性:通过定义认证和授权机制,Web API可以确保只有合法的客户端才能访问敏感的业务逻辑和数据。
实现步骤
创建项目
首先创建一个ASP.NET.core.web.API项目

添加管理包
右键点击“包”,再点击“管理NuGet程序包”即可

再搜索以下包,下载即可

存储用户信息
创建一个user类,这个是用来存储你的用户信息的(其中包含username,Email,password等等...)。同时,在数据库中也应该存在名为user的数据表

第三,在config文件夹中引用user的上下文
实现操作
在项目里创建一个文件夹分别名为Service,在Srvice文件夹中再创建一个文件夹名为Imp。
在Srvice文件夹中创建名为IEmailservice的接口,在Imp文件夹再创建名为EmailserviceImp的类
1.在IEmailservice的接口里输入以下代码
//发送电子邮件
public Task SendEmail(string toEmail,string subject,string body);
//邮箱登录
public ApiResponse<User> EmaiLogin(string email, string code);
在这串代码中第一行代码是用来发送登录时的验证码。
生成验证码的设置
创建三个EmailcodeVerilfication,JwtTokeOptions,CustomJWTService的类。在EmailcodeVerilfication的类中,这是一个用来生成项目发送过来的验证码。CustomJWTService类则是用来设置验证码发送者的名称和验证码生效的时间。JwtTokeOptions这个类是用来配置JwtTokeOptions的设置
1.CustomJWTService类代码如下
public class CustomJWTService
{
private readonly JwtTokeOptions _jwtOptions;
//构造函数的注入,接受optionsMonitor的实例
public CustomJWTService(IOptionsMonitor<JwtTokeOptions> optionsMonitor)
{
_jwtOptions=optionsMonitor.CurrentValue;//将当前的 optionsMonitor实例赋值给_jwtOptions
}
//生成JWT
public string GetToke(User user ,string roleName)
{
//1.需要把登录消息存放到Claim列表
var claims = new List<Claim>()
{
new Claim("Name",user.Name),
new Claim("Password",user.Password),
new Claim("Email",user.Email),
new Claim(ClaimTypes.Role,roleName)
};
//2.创建一个用于Jwt密钥加密
SymmetricSecurityKey key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtOptions.SecurityKey));
//3.创建一个签名凭据,指定算法
SigningCredentials signing = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
//4.设置一个Tokend的有效时间
var expires=DateTime.Now.AddMinutes(10);
//5.把前面4个步骤组在一起,创建TOKEN
JwtSecurityToken token = new JwtSecurityToken(
issuer:_jwtOptions.Issuer, //设置token发行人
audience:_jwtOptions.Audience, //设置token接受人
claims:claims,//设置token的用户登录信息
expires:expires,//设置token有效时间
signingCredentials:signing //设置token签名凭据
);
//6.将token序列化为字符串
string returnToken =new JwtSecurityTokenHandler().WriteToken(token);
return returnToken;
}
}
2.EmailcodeVerilfication类代码如下
public class EmailcodeVerilfication
{
private readonly IMemoryCache _cache;//内存缓存实例,用于验证码存储
/// <summary>
/// 构造函数,注入内存缓存服务
/// </summary>
/// <param name="code"></param>
public EmailcodeVerilfication(IMemoryCache cache)
{
_cache = cache;
}
/// <summary>
/// 生成验证码并存储到内存缓存中
/// </summary>
/// <param name="email">用户的邮件,用于缓存的健</param>
/// <param name="codeLength">验证码长度,默认为6</param>
/// <returns></returns>
public string GenerateAndStoreVerilficationCode(string email,int codeLength=6)
{
//获取随机生成验证码
var code = GeterateVerilficationCode(codeLength);
//生成验证码之后,将其设置有效时长为10分钟
_cache.Set(email, code, TimeSpan.FromMinutes(10));
return code;
}
/// <summary>
/// 随机生成验证码验证字符串
/// </summary>
/// <param name="length"></param>
/// <returns></returns>
public string GeterateVerilficationCode(int length)
{
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
//创建随机函数实例
var random=new Random();
//从字符集中随机选择字符,生成验证码
var code=new string(Enumerable.Repeat(chars, length).Select(s => s[random.Next(s.Length)]).ToArray());
return code;
}
/// <summary>
/// 验证码提供的验证码是否与缓存中的验证码匹配
/// </summary>
/// <param name="email">用户的邮箱</param>
/// <param name="code">用户提供的验证码</param>
/// <returns></returns>
public bool verifyCode(string email, string code)
{
string storeCode;
if(_cache.TryGetValue(email,out storeCode))//尝试从缓存中获取存储的验证码
{
if (string.Equals(code, storeCode, StringComparison.OrdinalIgnoreCase))//如果提供的验证码与存储在缓存的验证码匹配,就进入
{
_cache.Remove(email);//验证通过后,从缓存中移除验证码,保证验证码只能使用一次
return true;
}
}
return false;//如果验证码不存在或不匹配返回 false
}
}
3..JwtTokeOptions类代码如下
public class JwtTokeOptions
{
//令牌的发行者
public string Issuer { get; set; }
//令牌的接收者
public string Audience{ get; set; }
//用于签名的令牌密钥
public string SecurityKey { get; set; }
//令牌的有效时间
public string ValidityInMinutes { get; set; }
//令牌的算法
public string Algorithm { get; set; } = SecurityAlgorithms.HmacSha256;
}
实现验证码登录
EmailserviceImp类中继承IEmailservice的接口,进行模块私有化和构造函数注入,并实现接口
public class EmailServiceImp : IEmailservice
{
private readonly flowerContext _flowerContext;
private readonly EmailcodeVerilfication _emailcodeVerilfication;
private readonly CustomJWTService _customJWTService;
public EmailServiceImp( flowerContext flowerContext, EmailcodeVerilfication emailcodeVerilfication, CustomJWTService customJWTService)
{
_flowerContext = flowerContext;
_emailcodeVerilfication = emailcodeVerilfication;
_customJWTService = customJWTService;
}
public ApiResponse<User> EmaiLogin(string email, string code)
{
//1.需要判断邮箱是否存在,从数据库中查询
var users= _flowerContext.user.AsQueryable().Where(u => u.Email == email);
if (users.Any())
{
//2.如果存在,验证用户输入的验证码和内存缓存的验证码是否存在
if (_emailcodeVerilfication.verifyCode(email, code))
{
//获取根据邮箱查询到的数据第一个
var user=users.First();
//根据邮箱查询到的用户角色外键id,查询角色信息
Role ?role=_flowerContext.role.AsQueryable().Where(r=>r.Id==user.RoleID).FirstOrDefault();
//判端查询的角色信息是否为空,如果为空则设置角色为空字符串,不为空者给予对应的角色
var roleName=role!=null?role.Name:"";
//3.如果存在,把用户信息存储,并生成Token,登录成功
return new ApiResponse<User>()
{
StatusCode=200,
Message = "登录成功" ,
Data=user,
Token=_customJWTService.GetToke(user,roleName)
};
}
else
{
return new ApiResponse<User>() { StatusCode=500,Message = "验证码已过期或错误" };
}
}
return new ApiResponse<User>() { StatusCode = 500, Message = "账号不存在或没有注册!" };
}
/// <summary>
/// 发送电子邮件
/// </summary>
/// <param name="toEmail">邮件接受者</param>
/// <param name="subject">邮件主题</param>
/// <param name="body">邮件内容,正文</param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task SendEmail(string toEmail, string subject, string body)
{
//设置邮件发送者,地址
var emilAddress=new MailAddress("2422830090@qq.com","花卉科普项目");
//设置邮件接受人
var toAddress = new MailAddress(toEmail);
//设置发送人的qq邮箱密码,授权码
string formPassword = "waidksuqduazechj";
//创建客户端SMTP并配置属性
var smtp = new SmtpClient
{
//smtp服务器地址
Host="smtp.qq.com",
//端口号
Port=587,
//加密传输ssl,是否启用
EnableSsl = true,
//邮件发送方式
DeliveryMethod=SmtpDeliveryMethod.Network,
//是否使用默认凭据
UseDefaultCredentials = false,
//设置SMTP服务器登录凭据
Credentials=new NetworkCredential(emilAddress.Address,formPassword)
};
//创建邮件消息对象,设置邮件的发件人,收件人,主题和内容
using (var message=new MailMessage(emilAddress, toAddress){
Subject=subject,
Body=body
})
{
//异步发送邮件
await smtp.SendMailAsync(message);
}
}
}
收尾工作
在Program的文件夹中注册内存缓存服务,生成验证码服务和把服务层注入容器
//把服务层注入容器
builder.Services.AddScoped<IEmailservice,EmailServiceImp>();
//注册内存缓存服务
builder.Services.AddMemoryCache();
//注册生成验证码服务
builder.Services.AddSingleton<EmailcodeVerilfication>();
builder.Services.Configure<JwtTokeOptions>(builder.Configuration.GetSection("JWTTokenoptions"));
builder.Services.AddSingleton<CustomJWTService>();

16万+

被折叠的 条评论
为什么被折叠?



