ASP.NET前后端分离,WebApi。Vue3+ElementPlus+Axios+Pinia全流程教程

2024-05-13 1481阅读

文章目录

  • 前言
    • 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全流程教程

                          2、中间件的执行过程

                          ASP.NET前后端分离,WebApi。Vue3+ElementPlus+Axios+Pinia全流程教程

                          3、AOP切面编程

                          ASP.NET前后端分离,WebApi。Vue3+ElementPlus+Axios+Pinia全流程教程

                          ASP.NET前后端分离,WebApi。Vue3+ElementPlus+Axios+Pinia全流程教程

                          Swagger

                          添加Swagger注释

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

                          ASP.NET前后端分离,WebApi。Vue3+ElementPlus+Axios+Pinia全流程教程

                          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。Vue3+ElementPlus+Axios+Pinia全流程教程

                          4、添加实体类的Swagger注释

                          ASP.NET前后端分离,WebApi。Vue3+ElementPlus+Axios+Pinia全流程教程

                          ASP.NET前后端分离,WebApi。Vue3+ElementPlus+Axios+Pinia全流程教程

                          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全流程教程

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

                          ASP.NET前后端分离,WebApi。Vue3+ElementPlus+Axios+Pinia全流程教程

                          配置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();
                               
                            });
                            

                            使用扩展进行服务注册

                            1、创建utils文件夹

                            2、创建Swagger、AOP、JWT的类

                            Swagger

                            using Microsoft.OpenApi.Models;
                            using System.Reflection;
                            namespace Blog.Core.Helper
                            {
                                public static class SwaggerExt
                                {
                                    public static void AddSwagger(this IServiceCollection services)
                                    {
                                        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);
                                        });
                                    }
                                    public static void UseSwagger(this WebApplication application)
                                    {
                                        application.UseSwagger();
                                        application.UseSwaggerUI(c =>
                                        {
                                            c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
                                        });
                                    }
                                }
                            }
                            

                            AOP

                            using Autofac.Extensions.DependencyInjection;
                            using Autofac;
                            using Blog.Core.AOP;
                            using System.Reflection;
                            using Autofac.Extras.DynamicProxy;
                            namespace Blog.Core.Helper
                            {
                                public static class AOPAndIOCExt
                                {
                                    public static void AddAOP(this WebApplicationBuilder builder)
                                    {
                                        //IOC
                                        //builder.Services.AddTransient();
                                        //builder.Services.AddTransient();
                                        var basePath = AppContext.BaseDirectory;
                                        var servicesDllFile = Path.Combine(basePath, "Blog.Core.Services.dll"); //服务层
                                        var repositoryDllFile = Path.Combine(basePath, "Blog.Core.Repository.dll"); //仓储层
                                        if (!(File.Exists(servicesDllFile) && File.Exists(repositoryDllFile)))
                                        {
                                            throw new Exception("Repository.dll和service.dll 丢失,因为项目解耦了,所以需要先F6编译,再F5运行,请检查 bin 文件夹,并拷贝。");
                                        }
                                        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();
                                        });
                                    }
                                }
                            }
                            

                            JWT

                            using Microsoft.AspNetCore.Authentication.JwtBearer;
                            using Microsoft.IdentityModel.Tokens;
                            using System.Text;
                            namespace Blog.Core.Helper
                            {
                                public static class JWTExt
                                {
                                    public static void AddJWT(this WebApplicationBuilder builder)
                                    {
                                        builder.Services.AddSingleton(new Auth.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("System", policy => policy.RequireRole("System").Build());
                                            options.AddPolicy("SystemOrAdmin", policy => policy.RequireRole("Admin", "System"));
                                            options.AddPolicy("ClientOrAdmin", policy => policy.RequireRole("Admin", "Client"));
                                        });
                                    }
                                }
                            }
                            

                            3、在program类里进行 调用

                            using Autofac;
                            using Autofac.Extensions.DependencyInjection;
                            using Autofac.Extras.DynamicProxy;
                            using Blog.Core.AOP;
                            using Blog.Core.Auth;
                            using Blog.Core.Helper;
                            using Microsoft.AspNetCore.Authentication.JwtBearer;
                            using Microsoft.IdentityModel.Tokens;
                            using Microsoft.OpenApi.Models;
                            using System.Reflection;
                            using System.Text;
                            var builder = WebApplication.CreateBuilder(args);
                            // Add services to the container.
                            builder.Services.AddControllers();
                            builder.Services.AddMemoryCache();
                            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
                            #region JWT服务
                            builder.AddJWT();
                            #endregion
                            #region Swagger
                            builder.Services.AddEndpointsApiExplorer();
                            builder.Services.AddSwagger();
                            #endregion
                            #region AOPAndIOC
                            builder.AddAOP();
                            #endregion
                            //跨域
                            builder.Services.AddCors(options =>
                            {
                                options.AddPolicy("CorsPolicy", opt => opt.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod().WithExposedHeaders("X-Pagination"));
                            });
                            var app = builder.Build();
                            app.UseStaticFiles();
                            app.UseRouting();
                            app.UseCors("CorsPolicy");
                            // Configure the HTTP request pipeline.
                            if (app.Environment.IsDevelopment())
                            {
                                app.UseSwagger();
                            }
                            //启用验证中间件
                            app.UseAuthentication();
                            app.UseAuthorization();
                            app.MapControllers();
                            app.Run();
                            

                            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);
                            
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]