ASP.NET MVC实际项目中后端实现密码修改
密码修改
目录
项目结构(不是全部,只列出总纲和自己需要操作的部分,这里都是文件夹)
1.Model的创建(这里是为我们查询和更新信息建立对应数据库的实体)
3.接口的实现(implement),这里是数据库内容的具体操作
5.Bl层的构建(业务逻辑)在Dal和WebMVC中间,数据交换中承上启下。
6.Controller层代码构建,这一层定义方法,并调用Bl层
前言
本人是一位刚开始工作的萌新,首次接触ASP.NET项目,以前没也有学习过这个语言,入职一周后开始跟着做,整理了一下这个功能实现的过程,希望能给和我类似的人提供到一些帮助。没有写在小标题上的介绍会在注释里指出。第一次开始写自己的博客,有错误的话或者不足的地方希望各位指出,接下来也会持续更新工作任务中遇到的问题和功能实现。
项目中添加密码修改功能实现准备:
- 开发语言 c#
- 开发工具 visual studio 2019
- 数据库工具 navicat
- 单元测试工具 postman
功能设计要求:
- 需要输入三个参数 :UserAccount UserPassword UserOldPassword
- 输出内容无,修改成功后返回成功与否结果即可
功能实现梳理:
- 修改密码主要操作就是两个动作。一个是数据库用户信息查询比对(select),另一个就是数据库密码更新(update)。接下来我们按照我梳理的编号依次完成。
项目结构(不是全部,只列出总纲和自己需要操作的部分,这里都是文件夹)
Web.BL(业务逻辑层)
Web.Dal(数据访问层)
Web.Entities(实体层,对应数据库)
- Models
- ViewModels
Web.Tools(工具,具体信息还不清楚,待更新,目前没有用到)
WebMvc(表现层)
- Controllers
WebMvcDB(数据库操作层)
- DB
- DBImplement
- DBServices
1.Model的创建(这里是为我们查询和更新信息建立对应数据库的实体)
三个传进去的参数:
- UserAccount(数据库内的用户)
- UserPassword(需要修改的密码)
- UserOldePassword(数据库内的原密码)
Controller层(编号6)调用的model在ViewModel里 然后db传输dao(DB层接口)那边开始用Model(这个是我这个项目的要求,只在这里为了功能实现的话全部调用ViewModel里的model是可以执行的,当然对应的接口(dao)里面的方法引用的model和实现接口的部分也要修改)
Model所在位置在上面结构中,分为ViewModel和Model
ViewModel针对的前后台交互的输入输出model,一般用xxxxxRequestModel,xxxxResponseModel命名分别代表输入 输出
Model是mvc和mvcdb传输用的 ,一般用xxxxInModel和xxxxOutModel命名代表输入输出
这里修改密码是不需要输出的,更改的是数据库里内容,那么我们需要两个输入Model,分别命名为ChangePasswordRequestModel和ChangePasswordInModel
下面代码using是有不少多余的,我只截取了自己的代码出来,多余using没有清理。
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text;
namespace Web.Entities.ViewModels
{
/// <summary>
/// 密码变更需要的输入参数
/// </summary>
public class ChangePasswordRequestModel
{
public ChangePasswordRequest ChangePasswordRequest { get; set; }
}
public class ChangePasswordRequest
{
/// <summary>
/// 用户名
/// </summary>
[MaxLength(30)]
public string UserAccount { get; set; } //这样的称为属性
/// <summary>
/// 新密码(传到数据库里)
/// </summary>
[MaxLength(20)]
public string UserPassword { get; set; }
/// <summary>
/// 旧密码(数据库里)
/// </summary>
[MaxLength(20)]
public string OldUserPassword { get; set; }
}
}
namespace Web.Entities.Models
{
public class ChangePasswordInModel
{
/// <summary>
/// 用户名
/// </summary>
public string UserAccount { get; set; }
/// <summary>
/// 新密码(传到数据库里)
/// </summary>
public string UserPassword { get; set; }
/// <summary>
/// 旧密码(数据库里)
/// </summary>
public string OldUserPassword { get; set; }
}
}
2.DB层构建,先创建接口(Dao)这里是没有实际操作的
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Web.Entities.Models;
using Web.Entities.ViewModels;
namespace WebMvcDB.DB.DBServices
{
public interface IUserInfoDao
{
/// <summary>
/// 密码更新
/// </summary>
/// <param name="input">用户信息</param>
public Boolean ChangePassword(ChangePasswordInModel input);
}
}
3.接口的实现(implement),这里是数据库内容的具体操作
public Boolean ChangePassword(ChangePasswordInModel input)
{
//数据库的链接调用
WFContext wfContext = new WFContext();
//tbUserInfoMsts是我数据库里的表
IQueryable<TbUserInfoMst> tbUserInfoMsts
= wfContext.TbUserInfoMsts.AsQueryable();
List<TbUserInfoMst> tbUserInfoMstList
= new List<TbUserInfoMst>();
// 改变密码前的check,这里会通过where条件获取到我需要的数据库信息
tbUserInfoMstList = tbUserInfoMsts.Where
(m=>m.UserAccount.Equals(input.UserAccount)&&
m.UserPassword.Equals(input.OldUserPassword)&&
m.IsDel == 0).ToList();
TbUserInfoMst userInfoMst = new TbUserInfoMst();
if (!Util.IsEmpty(tbUserInfoMstList) && tbUserInfoMstList.Count != 0)
{
userInfoMst = tbUserInfoMstList.First();
}
else
{
return false;
}
/*
密码的更新操作,这里做了新旧密码相同时才更新,
但是实际应用时这个check抛给前台也可以
*/
if (input.UserPassword != input.OldUserPassword)
{
userInfoMst.UserPassword = input.UserPassword;
wfContext.Attach(userInfoMst);
wfContext.SaveChanges();
}
return true;
}
4.Dal层的构建(数据访问层),执行结果并返回布尔值
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Text;
using Web.Entities.Models;
using Web.Entities.ViewModels;
using WebMvcDB.DB.DBImplement;
using WebMvcDB.DB.DBServices;
namespace Web.Dal
{
public class HomeDal : BaseDal
{
/// <summary>
/// 密码修改
/// </summary>
/// <param name="input">用户信息</param>
/// <returns></returns>
public static WebReturn ChangePassword(ChangePasswordRequest input)
//WebReturn 是项目实体层(Entities)网页返回用的一个类
{
// IUserInfoDao接口实例化
IUserInfoDao tUserInfoDao = new TUserInfoImplement();
// 对应接口实现里面的密码修改的数据库操作
Boolean flag = tUserInfoDao.
ChangePassword(CastModel<ChangePasswordInModel>(input));
return Success(flag);
}
}
}
5.Bl层的构建(业务逻辑)在Dal和WebMVC中间,数据交换中承上启下。
using Microsoft.AspNetCore.Mvc.Filters;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
using Web.Dal;
using Web.Entities.Models;
using Web.Entities.ViewModels;
namespace Web.BL
{
public class HomeBl : BaseBl
{
/// <summary>
/// 密码更新
/// </summary>
/// <param name="input">UserAccount,UserPassword,UserOldPassword</param>
/// <returns>布尔类型结果</returns>
public static Boolean ChangePassword(ChangePasswordRequest input)
// 这里用Boolean定义是因为返回值是Boolean
{
/*
定义的WebReturn参数changePassword是
调用的Dal层里面的HomeDal的方法里输入的参数
*/
WebReturn changePassword = HomeDal.ChangePassword(input);
/*
JsonConvert.DeserializeObject<T>(string value)
是转换为反序列的obj类型的方法,直接调用即可
*/
return JsonConvert.DeserializeObject<Boolean>(changePassword.Data.ToString());
}
}
}
6.Controller层代码构建,这一层定义方法,并调用Bl层
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Threading.Tasks;
using Web.BL;
using Web.Entities;
using Web.Entities.Models;
using Web.Entities.ViewModels;
using Web.Entities.ViewModels.Base;
using Web.Tools;
namespace WebMvc.Controllers
{
[ApiController]
[Route("api/[controller]/[action]")]
public class HomeController : BaseController
{
public HomeController(IWebHostEnvironment env, IHttpContextAccessor ctx) : base(env, ctx)
{
}
/// <summary>
/// 密码更新操作
/// </summary>
/// <param name="ChangePassword"></param>
/// <returns></returns>
[HttpPost] //[***]是特性的写法,这里是指在post请求下执行
public async Task<ActionResult<ResponseRootModel>> ChangePassword([FromBody] ChangePasswordRequestModel ChangePassword)
上面这个方法
{
try
{
//此行可参考<a>https://www.cnblogs.com/dudu/p/task-yield.html<a>
await Task.Yield();
/*
ChangePassword.ChangePasswordRequest等同于
ChangePasswordRequestModel.ChangePasswordRequest,这里调用的viewmodel里的方法
*/
ChangePasswordRequest requestDataSet = ChangePassword.ChangePasswordRequest;
//报错时信息存放变量
ResponseHeaderModel headerModel = new ResponseHeaderModel();
/*
输入检查空值,这里注意Util.IsEmpty()不能用于
***.count(),用***.count()==0判断,.count()是元素个数的计量,
如果用null判断会出错
*/
if (requestDataSet == null || Util.IsEmpty(requestDataSet.UserAccount) ||
Util.IsEmpty(requestDataSet.UserPassword) || Util.IsEmpty(requestDataSet.OldUserPassword))
{
// 这里是错误信息显示,返回的是implement里面的flase
headerModel.MessageId = "SV_100001";
SetHeader(headerModel);
return Error();
}
// Booleanタイプ結果を取得
Boolean flg = HomeBl.ChangePassword(requestDataSet);
if (!flg)
{
headerModel.MessageId = "SV_200004";
SetHeader(headerModel);
return Error();
}
// 这里注意,成功执行返回的是空值,如果希望返回布尔值,可以用return Success(flg);
return Success();
}
catch (Exception e)
{
string errorMessage = "密码修改出错";
LogsHelper.WriteBothLog(NLog.LogLevel.Error, LogType.Web, new LogInfoModel("ERROR-0002", errorMessage), "", new Exception(errorMessage, e));
throw e;
}
}
}
}
7.单元测试
到这个环节的时候我们的单元内容已经结束,上面的流程顺序就是这个功能实现的过程。下面是对结果的其中一个测试,我用的是postman工具进行单元测试,安装和使用部分我就略过了。这里本来应该有一个login的check,和我的单元内容无关我就不贴了。
postman send后,这里测试的是数据库里的test3用户:
UseAccount = test3; UserPassword = Testsucceed; UserOldPassword = succeed
- 执行测试前数据库Test3密码为succeed:
- 修改后的密码为testsucceed
感谢观看。更新于2021/12/08