ASP.NET前后端分离,WebApi。Vue3+ElementPlus+Axios+Pinia全流程教程,ASP.NET WebApi与Vue 3 + ElementPlus + Axios + Pinia前后端分离开发全流程指南

马肤

温馨提示:这篇文章已超过442天没有更新,请注意相关的内容是否还可用!

摘要:本教程详细介绍了ASP.NET前后端分离技术,通过WebApi实现后端服务。前端采用Vue3、ElementPlus、Axios和Pinia等技术,全程指导开发者搭建项目框架、实现数据交互、组件开发以及状态管理。该教程内容全面,适合初学者和进阶开发者学习参考。

文章目录

  • 前言
    • 1、.net core 执行过程
    • 2、中间件的执行过程
    • 3、AOP切面编程
    • Swagger
      • 添加Swagger注释
      • JWT
        • 1、解析
        • 2、配置JWT
        • 配置SqlSugar
          • 0、引入`SqlSugarCore`包
          • 1、编写`Context`类
          • 2、配置实体类
          • 3、创建`Service`服务类进行数据库的CRUD
          • 4、配置Controller进行路由
          • 依赖注入与IOC
            • IOC
            • 依赖注入DI
            • Autofac轻量容器的使用
            • 使用Autofac完成AOP日志
            • Webapi的操作返回值和方法参数
              • 返回值ActionResult
              • 操作方法的参数
                • URL
                • QueryString
                • 请求报文体
                • 总结
                • VUE项目结构
                  • 主要文件
                  • 项目运行流程
                  • 添加Element-ui、AXIOS
                  • Axios与pinia
                    • AXIOS
                      • 使用npm等包管理工具下载axios
                      • 创建axios实例、封装get、post请求方法
                      • 封装api接口调用方法
                      • 在页面中调用api
                      • pinia使用
                        • 使用npm下载pinia
                        • 创建Store文件进行状态存储
                        • 在页面组件中实例化状态并赋值

                          前言

                          1、.net core 执行过程

                          ASP.NET前后端分离,WebApi。Vue3+ElementPlus+Axios+Pinia全流程教程,ASP.NET WebApi与Vue 3 + ElementPlus Axios Pinia前后端分离开发全流程指南 第1张

                          2、中间件的执行过程

                          ASP.NET前后端分离,WebApi。Vue3+ElementPlus+Axios+Pinia全流程教程,ASP.NET WebApi与Vue 3 + ElementPlus Axios Pinia前后端分离开发全流程指南 第2张

                          3、AOP切面编程

                          ASP.NET前后端分离,WebApi。Vue3+ElementPlus+Axios+Pinia全流程教程,ASP.NET WebApi与Vue 3 + ElementPlus Axios Pinia前后端分离开发全流程指南 第3张

                          ASP.NET前后端分离,WebApi。Vue3+ElementPlus+Axios+Pinia全流程教程,ASP.NET WebApi与Vue 3 + ElementPlus Axios Pinia前后端分离开发全流程指南 第4张

                          Swagger

                          添加Swagger注释

                          1、右击项目->选择属性->点击生成->输出,选中文档文件

                          ASP.NET前后端分离,WebApi。Vue3+ElementPlus+Axios+Pinia全流程教程,ASP.NET WebApi与Vue 3 + ElementPlus Axios Pinia前后端分离开发全流程指南 第5张

                          2、配置服务

                          在program.cs 文件里配置SwaggerUI

                          //增加项一
                          builder.Services.AddSwaggerGen(c=> {
                              c.SwaggerDoc("v1", new OpenApiInfo { Title = "Web API", Version = "v1" });
                              var xmlFile = $"{Assembly.GetEntryAssembly().GetName().Name}.xml";
                              var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                              c.IncludeXmlComments(xmlPath);
                          });
                          //增加项二
                          if (app.Environment.IsDevelopment())
                          {
                              app.UseSwagger();
                              app.UseSwaggerUI(c =>
                              {
                                  c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
                              }); 
                          }
                          

                          3、在控制器的方法上加上注释即可在swagger网页上看到注释

                          ASP.NET前后端分离,WebApi。Vue3+ElementPlus+Axios+Pinia全流程教程,ASP.NET WebApi与Vue 3 + ElementPlus Axios Pinia前后端分离开发全流程指南 第6张

                          ASP.NET前后端分离,WebApi。Vue3+ElementPlus+Axios+Pinia全流程教程,ASP.NET WebApi与Vue 3 + ElementPlus Axios Pinia前后端分离开发全流程指南 第7张

                          4、添加实体类的Swagger注释

                          ASP.NET前后端分离,WebApi。Vue3+ElementPlus+Axios+Pinia全流程教程,ASP.NET WebApi与Vue 3 + ElementPlus Axios Pinia前后端分离开发全流程指南 第8张

                          ASP.NET前后端分离,WebApi。Vue3+ElementPlus+Axios+Pinia全流程教程,ASP.NET WebApi与Vue 3 + ElementPlus Axios Pinia前后端分离开发全流程指南 第9张

                          JWT

                          1、解析

                          1)客户端向授权服务系统发起请求,申请获取“令牌”。

                          2)授权服务根据用户身份,生成一张专属“令牌”,并将该“令牌”以JWT规范返回给客户端

                          3)客户端将获取到的“令牌”放到http请求的headers中后,向主服务系统发起请求。主服务系统收到请求后会从headers中获取“令牌”,并从“令牌”中解析出该用户的身份权限,然后做出相应的处理(同意或拒绝返回资源)

                          2、配置JWT

                          1、添加NuGet包Microsoft.AspNetCore.Authentication.JwtBearer

                          2、在appsettings.json中添加JWT配置节点

                             "JWT": {
                              "SecKey": "Jamin1127!#@$%@%^^&*(~Czmjklneafguvioszb%yuv&*6WVDf5dw#5dfw6f5w6faW%FW^f5wa65f^AWf56", //密钥
                              "Issuer": "Jamin",  //发行者
                              "ExpireSeconds": 7200 //过期时间
                            }
                          

                          3、在Program类里进行服务注册

                          #region JWT服务
                          // 注册JWT服务
                          builder.Services.AddSingleton(new JwtHelper(builder.Configuration));
                          builder.Services.AddAuthentication( JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
                          {
                              options.TokenValidationParameters = new TokenValidationParameters()
                              {
                                  ValidateIssuer = true, //是否验证Issuer
                                  ValidIssuer = builder.Configuration["Jwt:Issuer"], //发行人Issuer
                                  ValidateAudience = false, //是否验证Audience      
                                  ValidateIssuerSigningKey = true, //是否验证SecurityKey
                                  IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:SecKey"])), //SecurityKey
                                  ValidateLifetime = true, //是否验证失效时间
                                  ClockSkew = TimeSpan.FromSeconds(30), //过期时间容错值,解决服务器端时间不同步问题(秒)
                                  RequireExpirationTime = true,
                              };
                          }
                          );
                          builder.Services.AddAuthorization(options =>
                          {
                          /***    "Client" 策略要求用户必须拥有 "Client" 角色才能访问相关资源。
                          "Admin" 策略要求用户必须拥有 "Admin" 角色才能访问相关资源。
                          "SystemOrAdmin" 策略要求用户必须拥有 "Admin" 或者 "System" 角色之一才能访问相关资源。***/
                              options.AddPolicy("Client", policy => policy.RequireRole("Client").Build());
                              options.AddPolicy("Admin", policy => policy.RequireRole("Admin").Build());
                              options.AddPolicy("SystemOrAdmin", policy => policy.RequireRole("Admin", "System"));
                          });
                          #endregion
                          //swagger里添加JWT授权
                              builder.Services.AddSwaggerGen(c=> {
                              c.SwaggerDoc("v1", new OpenApiInfo { Title = "Web API", Version = "v1" });
                              //开启注释
                              var xmlFile = $"{Assembly.GetEntryAssembly().GetName().Name}.xml";
                              var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                              c.IncludeXmlComments(xmlPath, true);
                              // 配置 JWT Bearer 授权
                              c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                              {
                                  Description = "JWT Authorization header using the Bearer scheme",
                                  Name = "Authorization",
                                  In = ParameterLocation.Header,
                                  Type = SecuritySchemeType.Http,
                                  Scheme = "bearer"
                              });
                              var securityScheme = new OpenApiSecurityScheme
                              {
                                  Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" }
                              };
                              var securityRequirement = new OpenApiSecurityRequirement { { securityScheme, new string[] { } } };
                              c.AddSecurityRequirement(securityRequirement);
                          });
                          //启用验证中间件
                          app.UseAuthentication();
                          app.UseAuthorization();
                          

                          4、创建JWT类进行Token配置

                          using Microsoft.IdentityModel.Tokens;
                          using System.Diagnostics;
                          using System.IdentityModel.Tokens.Jwt;
                          using System.Security.Claims;
                          using System.Text;
                          namespace Blog.core.Common.Auth
                          {
                              /// 
                              /// 授权JWT类
                              /// 
                              public class JwtHelper
                              {
                                  private readonly IConfiguration _configuration;
                                  /// 
                                  /// Token配置
                                  /// 
                                  /// 
                                  public JwtHelper(IConfiguration configuration)
                                  {
                                      _configuration = configuration;
                                  }
                                  
                                  /// 
                                  /// 创建Token 这里面可以保存自己想要的信息
                                  /// 
                                  /// 
                                  /// 
                                  /// 
                                  public string CreateToken(string username, string mobile)
                                  {
                                      try
                                      {
                                          // 1. 定义需要使用到的Claims
                                          var claims = new[]
                                          {
                                              new Claim("username", username),
                                              new Claim("mobile", mobile),
                                              /* 可以保存自己想要信息,传参进来即可
                                              new Claim("sex", "sex"),
                                              new Claim("limit", "limit"),
                                              new Claim("head_url", "xxxxx")
                                              */
                                          };
                                          // 2. 从 appsettings.json 中读取SecretKey
                                          var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:SecKey"]));
                                          // 3. 选择加密算法
                                          var algorithm = SecurityAlgorithms.HmacSha256;
                                          // 4. 生成Credentials
                                          var signingCredentials = new SigningCredentials(secretKey, algorithm);
                                          // 5. 根据以上,生成token
                                          var jwtSecurityToken = new JwtSecurityToken(
                                              _configuration["Jwt:Issuer"],    //Issuer
                                              _configuration["Jwt:ExpireSeconds"],  //ExpireSeconds
                                              claims,                          //Claims,
                                              DateTime.Now,                    //notBefore
                                              DateTime.Now.AddSeconds(30),     //expires
                                              signingCredentials               //Credentials
                                          );
                                          // 6. 将token变为string
                                          var token = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
                                          return token;
                                      }
                                      catch (Exception)
                                      {
                                          throw;
                                      }
                                     
                                  }
                                  /// 
                                  /// 获取信息
                                  /// 
                                  /// 
                                  /// 
                                  public static string ReaderToken(string jwt)
                                  {
                                      var str = string.Empty;
                                      try
                                      {
                                          //获取Token的三种方式
                                          //第一种直接用JwtSecurityTokenHandler提供的read方法
                                          var jwtHander = new JwtSecurityTokenHandler();
                                          JwtSecurityToken jwtSecurityToken = jwtHander.ReadJwtToken(jwt);
                                          str = jwtSecurityToken.ToString();
                                      }
                                      catch (Exception ex)
                                      {
                                          Debug.WriteLine(ex.Message);
                                      }
                                      return str;
                                  }
                                  /// 
                                  /// 解密jwt
                                  /// 
                                  /// 
                                  /// 
                                  public string JwtDecrypt(string jwt)
                                  {
                                     
                                      StringBuilder sb = new StringBuilder();
                                      try
                                      {
                                          JwtSecurityTokenHandler tokenHandler = new();
                                          TokenValidationParameters valParam = new();
                                          var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:SecKey"]));
                                          valParam.IssuerSigningKey = securityKey;
                                          valParam.ValidateIssuer = false;
                                          valParam.ValidateAudience = false;
                                          //解密
                                          ClaimsPrincipal claimsPrincipal = tokenHandler.ValidateToken(jwt,
                                                  valParam, out SecurityToken secToken);
                                          foreach (var claim in claimsPrincipal.Claims)
                                          {
                                              sb.Append($"{claim.Type}={claim.Value}");
                                          }
                                      }
                                      catch (Exception ex)
                                      {
                                          Debug.WriteLine(ex.Message);
                                      }
                                      return sb.ToString();
                                  }
                              }
                          }
                          

                          5、创建用户实体,进行用户密码的接收

                          using System.ComponentModel.DataAnnotations;
                          namespace Blog.core.Models
                          {
                              public class UserInfo
                              {
                                  /// 
                                  /// 其中 [Required] 表示非空判断,其他自己研究百度
                                  /// 
                                  [Required]
                                  public string UserName { get; set; }
                                  [Required]
                                  public string Password { get; set; }
                                  [Required]
                                  public string PhoneNumber { get; set; }
                          }
                          }
                          

                          6、创建控制器,进行JWT的APi调用

                          using Blog.core.Common.Auth;
                          using Blog.core.Models;
                          using Microsoft.AspNetCore.Authorization;
                          using Microsoft.AspNetCore.Mvc;
                          namespace Blog.core.Controllers
                          {
                             
                                  [Route("[controller]/[action]")]
                                  [ApiController]
                                  public class UserController : ControllerBase
                                  {
                                      private readonly JwtHelper _jwt;
                                      /// 
                                      /// 初始化
                                      /// 
                                      /// 
                                      public UserController(JwtHelper jwtHelper)
                                      {
                                          _jwt = jwtHelper;
                                      }
                                      /// 
                                      /// 获取Token
                                      /// 
                                      /// 
                                      [HttpPost]
                                      public IActionResult GetToken(UserInfo user)
                                      {
                                          //参数验证等等....
                                          if (string.IsNullOrEmpty(user.UserName))
                                          {
                                              return Ok("参数异常!");
                                          }
                                          //这里可以连接mysql数据库做账号密码验证
                                          //这里可以做Redis缓存验证等等
                                          //这里获取Token,当然,这里也可以选择传结构体过去
                                          var token = _jwt.CreateToken(user.UserName, user.PhoneNumber);
                                            //解密后的Token
                                            var PWToken = _jwt.JwtDecrypt( token);
                                            return Ok(token+"解密后:"+PWToken);
                               
                                      }
                                      /// 
                                      /// 获取自己的详细信息,其中 [Authorize] 就表示要带Token才行
                                      /// 
                                      /// 
                                      [HttpPost]
                                      [Authorize]
                                      public IActionResult GetSelfInfo()
                                      {
                                          //执行到这里,就表示已经验证授权通过了
                                          /*
                                           * 这里返回个人信息有两种方式
                                           * 第一种:从Header中的Token信息反向解析出用户账号,再从数据库中查找返回
                                           * 第二种:从Header中的Token信息反向解析出用户账号信息直接返回,当然,在前面创建        Token时,要保存进使用到的Claims中。
                                          */
                                          return Ok("授权通过了!");
                                      }
                                  }  
                          }
                          

                          7、用来验证权限的控制器

                          using Microsoft.AspNetCore.Authorization;
                          using Microsoft.AspNetCore.Mvc;
                          namespace Blog.core.Controllers
                          {
                             
                              [ApiController]
                              [Route("[controller]")]
                              [Authorize(Roles ="Admin")]
                              [Authorize(Roles ="User")]//增加权限验证
                              public class WeatherForecastController : ControllerBase 
                              {
                                  private static readonly string[] Summaries = new[]
                                  {
                                      "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
                                  };
                                  private readonly ILogger _logger;    
                                  public WeatherForecastController(ILogger logger)
                                  {
                                      _logger = logger;
                                  }
                                  /// 
                                  /// 天气
                                  /// 
                                  /// 
                                  [HttpGet]
                                  public IEnumerable Get()
                                  {
                                      return Enumerable.Range(1, 5).Select(index => new WeatherForecast
                                      {
                                          Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
                                          TemperatureC = Random.Shared.Next(-20, 55),
                                          Summary = Summaries[Random.Shared.Next(Summaries.Length)]
                                      })
                                      .ToArray();
                                  }
                                 
                              }
                          }
                          

                          ASP.NET前后端分离,WebApi。Vue3+ElementPlus+Axios+Pinia全流程教程,ASP.NET WebApi与Vue 3 + ElementPlus Axios Pinia前后端分离开发全流程指南 第10张

                          **注:获取Token后在Swagger上输入token的value就可以进行接口的调用了 **

                          ASP.NET前后端分离,WebApi。Vue3+ElementPlus+Axios+Pinia全流程教程,ASP.NET WebApi与Vue 3 + ElementPlus Axios Pinia前后端分离开发全流程指南 第11张

                          配置SqlSugar

                          0、引入SqlSugarCore包

                          1、编写Context类

                            public static SqlSugarClient db = new SqlSugarClient(
                                            new ConnectionConfig()
                                            {
                                                ConnectionString = "server = 127.0.0.1; Database = test; Uid = root; Pwd = root; AllowLoadLocalInfile = true;",
                                                DbType = DbType.MySql,//设置数据库类型
                                                IsAutoCloseConnection = true,//自动释放数据务,如果存在事务,在事务结束后释放
                                            });
                          

                          2、配置实体类

                          using SqlSugar;
                          using System;
                          using System.Collections.Generic;
                          using System.Linq;
                          using System.Text;
                          using System.Threading.Tasks;
                          namespace Blog.Core.Model.Models
                          {
                              [SugarTable(tableName: "Person")]
                              public class User
                              {
                                  [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
                                  public int Id { get; set; }
                                  public int Age { get; set; }
                                  public string? Name { get; set; }
                              }
                          }
                          

                          3、创建Service服务类进行数据库的CRUD

                          using Blog.core.IRepository;
                          using Blog.Core.Model.Models;
                          using static Blog.Core.Common.DbContext;
                          namespace Blog.Core.Repository
                          {
                              public class UserRepository : IUserRepository
                              {
                                  public  int Add(User user)
                                  {
                                      var line = db.Insertable(user).ExecuteCommand();
                                      return line;
                                  }
                                  public int Delete(int UserId)
                                  {
                                      var line = db.Deleteable(new User
                                      {
                                          Id = UserId
                                      }).ExecuteCommand();
                                      return line;
                                  }
                                  public List GetUsers(int Id)
                                  {
                                      List users;
                                      if (Id is not 0)
                                      {
                                          users = db.Queryable().Where(it => it.Id == Id).ToList();
                                      }
                                      else
                                      {
                                          users = db.Queryable().ToList();
                                      }
                                      return users;
                                  }
                                  public int Update(User user)
                                  {
                                      var res = db.Updateable(user).ExecuteCommand();
                                      return res;
                                  }
                              }
                          }
                          

                          4、配置Controller进行路由

                          using Blog.core.Models;
                          using Blog.Core.Auth;
                          using Blog.Core.IServices;
                          using Blog.Core.Model.Models;
                          using Microsoft.AspNetCore.Authorization;
                          using Microsoft.AspNetCore.Mvc;
                          using Blog.Core.Services;
                          namespace Blog.core.Controllers
                          {
                              [Route("[controller]/[action]")]
                                  [ApiController]
                                  public class UserController : ControllerBase
                                  {
                                      private readonly IUserService _userService;
                                      public UserController( IUserService userService)
                                          {
                                              _userService = userService;
                                          }
                                          /// 
                                          /// 增加
                                          /// 
                                          /// 
                                          /// 
                                          [HttpPost]
                                          public int AddUser(User user)
                                          {
                                              // User user = new User() { Id = 2024325, Name = "Czm", Age = 20 };
                                              return _userService.Add(user);
                                          }
                                          /// 
                                          /// 删除
                                          /// 
                                          /// 
                                          /// 
                                          [HttpDelete]
                                          public int DeleteUser(int id)
                                          {
                                              return _userService.Delete(id);
                                          }
                                          /// 
                                          /// 更新
                                          /// 
                                          /// 
                                          /// 
                                          [HttpPut]
                                          public int UpdateUsre(User user)
                                          {
                                              return _userService.Update(user);
                                          }
                                          /// 
                                          /// 获取数据
                                          /// 
                                          /// 
                                          /// 
                                          [HttpGet]
                                          public List GetUser(int id)
                                          {
                                              return _userService.GetUsers(id);
                                          }
                              }
                          }
                          

                          依赖注入与IOC

                          IOC

                          IOC 是 Inversion of Control(控制反转)的缩写。在软件开发中,IOC 是一种设计模式,它改变了传统的程序设计流程,使得对象之间的依赖关系由代码本身控制变为由外部容器控制。

                          而采用IOC 设计模式后,对象之间的依赖关系由外部容器来管理和注入,对象本身不需要关心依赖的具体实现,只需要定义自己的接口或抽象类,并在外部容器中配置依赖关系。这样可以降低代码的耦合度,提高代码的灵活性、可维护性和可扩展性。

                          常见的IOC 容器包括 Spring Framework 中的 Spring IoC ,dotnet中的autofoc,它通过依赖注入(Dependency Injection)的方式来实现控制反转。通过IOC 容器,可以将对象之间的依赖关系集中管理,实现了代码的松耦合,使得程序更易于理解、扩展和维护。

                          依赖注入DI

                          1、继承接口并实现构造方法

                           public class UserService : IUserService
                           {
                               private  IUserRepository _userService ;
                               public UserService(IUserRepository userService)
                               {
                                   _userService = userService;
                               }
                           }
                          

                          2、在program里加上

                          builder.Services.AddTransient();
                          builder.Services.AddTransient();
                          

                          .net提供了三种生命周期的容器

                          builder.Services.AddTransient(); builder.Services.AddScoped(); builder.Services.AddSingleton();

                          • 暂时性对象始终不同。 IndexModel 和中间件中的临时 OperationId 值不同。
                          • 范围内对象对给定请求而言是相同的,但在每个新请求之间不同。
                          • 单一实例对象对于每个请求是相同的。

                            3、Controller层使用

                             public class UserController : ControllerBase
                             {
                                 private readonly IUserService _userService ;
                                 public UserController(IUserService userService)
                                 {
                                     _userService = userService;
                                 }
                             }
                            

                            Autofac轻量容器的使用

                            1、安装Nuget包Autofac.Extensions.DependencyInjection和Autofac.Extras.DynamicProxy

                            2、使用程序集注册,通过Model注册(这里只列这一种Auto官方文档Assembly Scanning — Autofac 7.0.0 documentation)

                            **创建Model类 **

                            using Autofac;
                            using Blog.Core.IServices;
                            using Microsoft.AspNetCore.Mvc;
                            using Microsoft.Extensions.DependencyModel;
                            using System.Reflection;
                            using System.Runtime.Loader;
                            namespace Blog.Core.Configuration.AutoModule
                            {
                                public class ServiceModel: Autofac.Module
                                {
                                    protected override void Load(ContainerBuilder builder)
                                    {
                                        // 自动对集成 IDependency 接口的类进行注册
                                        Type baseType = typeof(IUserService);
                                        var compilationLibrary = DependencyContext.Default.CompileLibraries.Where(x => !x.Serviceable && x.Type == "project").ToList();
                                        List assemblyList = new List();
                                        foreach (var _compilation in compilationLibrary)
                                        {
                                            try
                                            {
                                                assemblyList.Add(AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(_compilation.Name)));
                                            }
                                            catch (Exception ex)
                                            {
                                                Console.WriteLine(_compilation.Name + ex.Message);
                                            }
                                        }
                                        builder.RegisterAssemblyTypes(assemblyList.ToArray()).Where(type => baseType.IsAssignableFrom(type) && !type.IsAbstract)
                                            .AsSelf()
                                            .AsImplementedInterfaces()
                                            .PropertiesAutowired()
                                            .InstancePerLifetimeScope();
                                        var controllersTypesInAssembly = typeof(Program).Assembly.GetExportedTypes()
                                            .Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToArray();
                                        builder.RegisterTypes(controllersTypesInAssembly).PropertiesAutowired();
                                    }
                                }
                            }
                            

                            **在program.cs中解析Model **

                            builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
                            builder.Host.ConfigureContainer(i => i.RegisterModule());
                            builder.Services.AddControllers().AddControllersAsServices();
                            

                            在Controller中使用

                            public class UserController : ControllerBase
                            {
                                private readonly IUserService _userService ;
                                public UserController(IUserService userService)
                                {
                                    _userService = userService;
                                }
                            }
                            

                            使用Autofac完成AOP日志

                            1、编写AOP类

                            using Castle.DynamicProxy;
                            using Newtonsoft.Json;
                            using StackExchange.Profiling;
                            using System.Reflection;
                            namespace Blog.Core.AOP
                            {
                                /// 
                                /// 拦截器BlogLogAOP 继承IInterceptor接口
                                /// 
                                public class BlogLogAOP : IInterceptor
                                { 
                                    /// 
                                    /// 实例化IInterceptor唯一方法
                                    /// 
                                    /// 包含被拦截方法的信息
                                    public void Intercept(IInvocation invocation)
                                    {
                                        string UserName = "Jamin";
                                        //记录被拦截方法信息的日志信息
                                        var dataIntercept = "" +
                                            $"【当前操作用户】:{UserName} \r\n" +
                                            $"【当前执行方法】:{invocation.Method.Name} \r\n" +
                                            $"【携带的参数有】: {string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray())} \r\n";
                                        try
                                        {
                                            MiniProfiler.Current.Step($"执行Service方法:{invocation.Method.Name}() -> ");
                                            //在被拦截的方法执行完毕后 继续执行当前方法,注意是被拦截的是异步的
                                            invocation.Proceed();
                                            // 异步获取异常,先执行
                                            if (IsAsyncMethod(invocation.Method))
                                            {
                                                //Wait task execution and modify return value
                                                if (invocation.Method.ReturnType == typeof(Task))
                                                {
                                                    invocation.ReturnValue = InternalAsyncHelper.AwaitTaskWithPostActionAndFinally(
                                                        (Task)invocation.ReturnValue,
                                                        ex =>
                                                        {
                                                            LogEx(ex, ref dataIntercept);
                                                        });
                                                }
                                                else //Task
                                                {
                                                    invocation.ReturnValue = InternalAsyncHelper.CallAwaitTaskWithPostActionAndFinallyAndGetResult(
                                                     invocation.Method.ReturnType.GenericTypeArguments[0],
                                                     invocation.ReturnValue,
                                                     ex =>
                                                     {
                                                         LogEx(ex, ref dataIntercept);
                                                     });
                                                }
                                            }
                                            else
                                            {// 同步1           
                                             
                                            }
                                        }
                                        catch (Exception ex)// 同步2
                                        {
                                            LogEx(ex, ref dataIntercept);
                                        }
                                        var type = invocation.Method.ReturnType;
                                        if (typeof(Task).IsAssignableFrom(type))
                                        {
                                            var resultProperty = type.GetProperty("Result");
                                            dataIntercept += ($"【执行完成结果】:{JsonConvert.SerializeObject(resultProperty.GetValue(invocation.ReturnValue))}");
                                        }
                                        else
                                        {
                                            dataIntercept += ($"【执行完成结果】:{invocation.ReturnValue}");
                                        }
                                        // 你的日志记录 比如log4
                                        #region 输出到当前项目日志
                                        var path = Directory.GetCurrentDirectory() + @"\Log";
                                        if (!Directory.Exists(path))
                                        {
                                            Directory.CreateDirectory(path);
                                        }
                                        string fileName = path + $@"\InterceptLog-{DateTime.Now.ToString("yyyyMMddHHmmss")}.log";
                                        StreamWriter sw = File.AppendText(fileName);
                                        sw.WriteLine(dataIntercept);
                                        sw.Close();
                                        #endregion
                                    }
                                    private void LogEx(Exception ex, ref string dataIntercept)
                                    {
                                        if (ex != null)
                                        {
                                            //执行的 service 中,收录异常
                                            MiniProfiler.Current.CustomTiming("Errors:", ex.Message);
                                            //执行的 service 中,捕获异常
                                            dataIntercept += ($"方法执行中出现异常:{ex.Message + ex.InnerException}\r\n");
                                        }
                                    }
                                    public static bool IsAsyncMethod(MethodInfo method)
                                    {
                                        return (
                                            method.ReturnType == typeof(Task) ||
                                            (method.ReturnType.IsGenericType && method.ReturnType.GetGenericTypeDefinition() == typeof(Task))
                                            );
                                    }
                                }
                                internal static class InternalAsyncHelper
                                {
                                    public static async Task AwaitTaskWithPostActionAndFinally(Task actualReturnValue, Action finalAction)
                                    {
                                        Exception exception = null;
                                        try
                                        {
                                            await actualReturnValue;
                                        }
                                        catch (Exception ex)
                                        {
                                            exception = ex;
                                        }
                                        finally
                                        {
                                            finalAction(exception);
                                        }
                                    }
                                    public static async Task AwaitTaskWithPostActionAndFinallyAndGetResult(Task actualReturnValue, Func postAction, Action finalAction)
                                    {
                                        Exception exception = null;
                                        try
                                        {
                                            var result = await actualReturnValue;
                                            await postAction();
                                            return result;
                                        }
                                        catch (Exception ex)
                                        {
                                            exception = ex;
                                            throw;
                                        }
                                        finally
                                        {
                                            finalAction(exception);
                                        }
                                    }
                                    public static object CallAwaitTaskWithPostActionAndFinallyAndGetResult(Type taskReturnType, object actualReturnValue, Action finalAction)
                                    {
                                        return typeof(InternalAsyncHelper)
                                            .GetMethod("AwaitTaskWithPostActionAndFinallyAndGetResult", BindingFlags.Public | BindingFlags.Static)
                                            .MakeGenericMethod(taskReturnType)
                                            .Invoke(null, [actualReturnValue, finalAction]);
                                    }
                                }
                            }
                            

                            2、进行服务注册

                            builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
                            builder.Host.ConfigureContainer(build =>
                            {
                                // AOP 
                                var cacheType = new List();
                                build.RegisterType();    
                                cacheType.Add(typeof(BlogLogAOP));
                                // 获取 Service.dll 程序集服务,并注册
                                var assemblysServices = Assembly.LoadFrom(servicesDllFile);
                                build.RegisterAssemblyTypes(assemblysServices)
                                            .AsImplementedInterfaces()
                                            .InstancePerDependency()
                                            .EnableInterfaceInterceptors()//引用Autofac.Extras.DynamicProxy;
                                            .InterceptedBy(cacheType.ToArray());//允许将拦截器服务的列表分配给注册。
                                // 获取 Repository.dll 程序集服务,并注册
                                var assemblysRepository = Assembly.LoadFrom(repositoryDllFile);
                                build.RegisterAssemblyTypes(assemblysRepository)
                                        .AsImplementedInterfaces()
                                        .InstancePerDependency();
                               
                            });
                            

                            Webapi的操作返回值和方法参数

                            返回值ActionResult

                            ASP.NET Core Web API中的操作方法的返回值如果是普通数据类型,那么返回值就会默认被序列化为JSON格式的响应报文体返回。

                            1  [HttpGet("{id}")] 
                            2  public ActionResult GetPerson(int id) 
                            3  { 
                            4     if (id  user } from "@/store/Store";
                            const requestUrl = "http://localhost:5250";
                            const userStore = user();
                            //创建实例
                            const axiosInstance = axios.create({
                              baseURL: requestUrl,
                              // timeout: 3000,
                            });
                            //请求拦截器,请求前
                            axiosInstance.interceptors.request.use(
                              (config) = {
                                if (userStore.data) {
                                  // console.log("请求头toekn=====>", userStore.data.token);
                                  // 设置请求头
                                  // config.headers['token'] = useToken.token;
                                  config.headers.Authorization = `Bearer ${userStore.data.token}`;
                                }
                                return config;
                              },
                              (error) => {
                                return Promise.reject(error);
                              }
                            );
                            //请求拦截器,请求后
                            axiosInstance.interceptors.response.use(
                              (response) => {
                                if (response.status === 200) return response.data;
                              },
                              (error) => {
                                console.log(error);
                                const status: number = error.response.status;
                                switch (status) {
                                  case 404:
                                    console.error("资源不存在");
                                    break;
                                  case 401:
                                    console.error("没有权限");
                                    break;
                                  case 500:
                                  case 501:
                                  case 502:
                                    console.error("没有权限");
                                    break;
                                  case 400:
                                    console.error(error.response.data.msg + "参数错误");
                                    break;
                                  default:
                                    console.log("无法识别");
                                    break;
                                }
                                return Promise.reject(error);
                              }
                            );
                            interface ActionResult {
                              data: T;
                              msg: string;
                              error: any;
                              code: number;
                            }
                            //get请求
                            export const get = (
                              url: string,
                              params?: Object
                            ): Promise => {
                              return axiosInstance.get(url, { params });
                            };
                            //post请求
                            export const post = (
                              url: string,
                              data?: Object
                            ): Promise => {
                              return axiosInstance.post(url, data);
                            };
                            //put请求
                            export const put = (
                              url: string,
                              data?: Object
                            ): Promise => {
                              return axiosInstance.put(url, data);
                            };
                            //delete请求
                            export const delete1 = (
                              url: string,
                              params?: Object
                            ): Promise => {
                              return axiosInstance.delete(url, { params });
                            };
                            

                            封装api接口调用方法

                            import { get, post, delete1, put } from "./request";
                            import { user } from "@/types/index";
                            export const loginApi = (data: user) => {
                              return post("/api/Login/login", data);
                            };
                            export const getUserInfo = (ID: string) => {
                              return get("/api/Index/UserInfo", { ID });
                            };
                            

                            在页面中调用api

                            import { loginApi } from "@/common/api";
                            const emailLoginApi = async () => {
                              phoneLoding.value = true;
                              try {
                                const res = await loginApi({
                                  EMAIL: emailNumber.value,
                                  PASSWORD: PassWard.value,
                                });
                                // localStorage.setItem("userInfo", JSON.stringify(res.data.token));
                                // Cookies.set("token", res.data.token);
                                console.log(res);
                                userStore.setData(res.data);
                                console.log(userStore.data);
                                $router.push("/index");
                                phoneLoding.value = false;
                              } catch (error) {
                                phoneLoding.value = false;
                              }
                            };
                            

                            pinia使用

                            使用npm下载pinia

                            npm i pinia

                            创建Store文件进行状态存储

                            import { defineStore } from "pinia";
                            export const user = defineStore("userInfo", {
                              state: () => ({
                                data: { id: "", Name: "", token: "", Email: "" },
                              }),
                              actions: {
                                setData(payload: any) {
                                  this.data = payload;
                                },
                              },
                            });
                            

                            在页面组件中实例化状态并赋值

                            import { user } from "@/store/Store";
                            const userStore = user(); // 实例化 store
                            userStore.setData(res.data);
                            

0
收藏0
文章版权声明:除非注明,否则均为VPS857原创文章,转载或复制请以超链接形式并注明出处。

相关阅读

  • 【研发日记】Matlab/Simulink自动生成代码(二)——五种选择结构实现方法,Matlab/Simulink自动生成代码的五种选择结构实现方法(二),Matlab/Simulink自动生成代码的五种选择结构实现方法详解(二)
  • 超级好用的C++实用库之跨平台实用方法,跨平台实用方法的C++实用库超好用指南,C++跨平台实用库使用指南,超好用实用方法集合,C++跨平台实用库超好用指南,方法与技巧集合
  • 【动态规划】斐波那契数列模型(C++),斐波那契数列模型(C++实现与动态规划解析),斐波那契数列模型解析与C++实现(动态规划)
  • 【C++】,string类底层的模拟实现,C++中string类的模拟底层实现探究
  • uniapp 小程序实现微信授权登录(前端和后端),Uniapp小程序实现微信授权登录全流程(前端后端全攻略),Uniapp小程序微信授权登录全流程攻略,前端后端全指南
  • Vue脚手架的安装(保姆级教程),Vue脚手架保姆级安装教程,Vue脚手架保姆级安装指南,Vue脚手架保姆级安装指南,从零开始教你如何安装Vue脚手架
  • 如何在树莓派 Raspberry Pi中本地部署一个web站点并实现无公网IP远程访问,树莓派上本地部署Web站点及无公网IP远程访问指南,树莓派部署Web站点及无公网IP远程访问指南,本地部署与远程访问实践,树莓派部署Web站点及无公网IP远程访问实践指南,树莓派部署Web站点及无公网IP远程访问实践指南,本地部署与远程访问详解,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南。
  • vue2技术栈实现AI问答机器人功能(流式与非流式两种接口方法),Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法探究,Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法详解
  • 发表评论

    快捷回复:表情:
    评论列表 (暂无评论,0人围观)

    还没有评论,来说两句吧...

    目录[+]

    取消
    微信二维码
    微信二维码
    支付宝二维码