ASP.NET MVC实际项目中后端实现密码修改

密码修改

目录

密码修改

前言

项目结构(不是全部,只列出总纲和自己需要操作的部分,这里都是文件夹)

1.Model的创建(这里是为我们查询和更新信息建立对应数据库的实体)

2.DB层构建,先创建接口(Dao)这里是没有实际操作的

3.接口的实现(implement),这里是数据库内容的具体操作

4.Dal层的构建(数据访问层),执行结果并返回布尔值

5.Bl层的构建(业务逻辑)在Dal和WebMVC中间,数据交换中承上启下。

6.Controller层代码构建,这一层定义方法,并调用Bl层

7.单元测试


前言

        本人是一位刚开始工作的萌新,首次接触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,分别命名为ChangePasswordRequestModelChangePasswordInModel

下面代码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

 

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>