第4章 角色Api控件器的实现与调试

自定义管道中间件

1.1 WebApi.Middleware.CorsMiddleware

namespace WebApi.Middleware

{

    ///

    /// 【跨域访问中间件--类】

    ///

    /// 摘要:

    ///     该管道中间件类主要为了解决在由vue/uni-app前端项目(Cors)访问当前后端项目时,浏览器或App中出现的异常:

    ///    1“has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.”

    ///    2“has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.”

    ///

    ///

    public class CorsMiddleware

    {

        #region 拷贝构造方法与变量

        ///

        /// 【下1个】

        ///

        /// 摘要:

        ///     .Net(Core)框架内置管道中的下1个管道中间件实例。

        ///

        ///

        private readonly RequestDelegate _next;

        /// name="next">.Net(Core)框架内置管道中的下1个管道中间件实例。

        ///

        /// 【拷贝构造方法】

        ///

        /// 摘要:

        ///    通过该构造方法中的参数实例,实例化.Net(Core)框架内置管道中的下1个管道中间件实例。

        ///

        ///

        public CorsMiddleware(RequestDelegate next)

        {

            _next = next;

        }

        #endregion

        #region 方法

        /// name="context">HTTP上下文实例。

        ///

        /// 【异步调用】

        ///

        /// 摘要:

        ///    通过该方法向.Net(Core)框架内置管道中集成当前管道中间件,解决由vue/uni-app前端项目(Cors)访问当前后端项目时,浏览器或App中出现的异常:

        ///    1“has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.”

        ///    2“has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.”

        ///

        ///

        public async Task InvokeAsync(HttpContext context)

        {

            //解决在由Hbuilder创建的前端Xuni-app项目(Cors)访问当前后端项目时,浏览器或App中会出现异常:

            //“has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.”

            if (!context.Response.Headers.ContainsKey("Access-Control-Allow-Headers"))

            {

                context.Response.Headers.Add("Access-Control-Allow-Headers", "DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization");

            }

            if (!context.Response.Headers.ContainsKey("Access-Control-Allow-Methods"))

            {

                context.Response.Headers.Add("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,PATCH,OPTIONS");

            }

            //解决在由Hbuilder创建的前端Xuni-app项目(Cors)访问当前后端项目时,浏览器或App中会出现异常:

            //“has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.”

            if (!context.Response.Headers.ContainsKey("Access-Control-Allow-Origin"))

            {

                context.Response.Headers.Add("Access-Control-Allow-Origin", "*");

            }

            await _next(context);

        }

        #endregion

    }

}

1.2 WebApi.Middleware.SwaggerHomeMiddleware

namespace WebApi.Middleware

{

    ///

    /// Swagger主页中间件--类】

    ///

    /// 摘要:

    ///     该管道中间件类主要为了把“/Swagger/index.html”设定为默认启动页面,在IIS部署后,

    /// 通过当前管道中间件把根路由强制自动跳转到根路由”+“/Swagger/index.html”,从而避免根路由页面中“404”错误的出现。

    ///

    ///

    public class SwaggerHomeMiddleware

    {

        #region 拷贝构造方法与变量

        ///

        /// 【下1个】

        ///

        /// 摘要:

        ///     .Net(Core)框架内置管道中的下1个管道中间件实例。

        ///

        ///

        private readonly RequestDelegate _next;

        /// name="next">.Net(Core)框架内置管道中的下1个管道中间件实例。

        ///

        /// 【拷贝构造方法】

        ///

        /// 摘要:

        ///    通过该构造方法中的参数实例,实例化.Net(Core)框架内置管道中的下1个管道中间件实例。

        ///

        ///

        public SwaggerHomeMiddleware(RequestDelegate next)

        {

            _next = next;

        }

        #endregion

        #region 方法

        /// name="context">HTTP上下文实例。

        ///

        /// 【异步调用】

        ///

        /// 摘要:

        ///    通过该方法向.Net(Core)框架内置管道中间件集成当前管道中间件,把“/Swagger/index.html”设定为默认启动页面,在IIS部署后,

        ///  通过当前管道中间件把根路由强制自动跳转到根路由”+“/Swagger/index.html”,从而避免根路由页面中“404”错误的出现。

        ///

        ///

        public async Task InvokeAsync(HttpContext context)

        {

            if (context.Request.Path == "/")

            {

                context.Response.Redirect("/Swagger/index.html");

                return;

            }

            await _next(context);

        }

        #endregion

    }

}

2 重构Program.cs

using Data;

using Microsoft.EntityFrameworkCore;

using Microsoft.OpenApi.Models;

using System.Reflection;

using System.Runtime.InteropServices;

using WebApi.Middleware;

var builder = WebApplication.CreateBuilder(args);

//“Microsoft.EntityFrameworkCore.SqlServer”中间件实例,依赖注入到.Net(Core)6框架内置容器中。

builder.Services.AddDbContext<EFCoreContext>(

    //通过“DbContextOptionsBuilder”实例中的参数实例,为“Microsoft.EntityFrameworkCore.SqlServer”中间件的实例化提供参数实例,

    //最终把“Microsoft.EntityFrameworkCore.SqlServer”中间件实例,依赖注入到.Net(Core)6框架内置容器中。

    //IIS发布部署连接字符串必须使用“SQL Server身份认证数据库连接方式,才能实现发布部署程序与数据库的CURD的操作。

    options => options.UseSqlServer(builder.Configuration.GetConnectionString("SqlServerSQL")));

builder.Services.AddControllers();

// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle

builder.Services.AddEndpointsApiExplorer();

//通过AddSwaggerGen依赖注入中间,获取Api控制器方法的版本控制信息和注释等数据信息,依赖注入.Net7框架的内置容器中,为在“index.html”页面上渲染显示这些信息,作好预处理操作。

builder.Services.AddSwaggerGen(options => {

    options.SwaggerDoc("v1",

        new OpenApiInfo

        {

            Version = "v1",

            Title = $"接口文档—{RuntimeInformation.FrameworkDescription}",

        });

    //获取"UserServer.xml"文件的文件名。

    string _xmlFileName = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";

    //获取"WebApi.xml"文件的绝对路径。

    string _xmlFilePath = Path.Combine(AppContext.BaseDirectory, _xmlFileName);

    //把控件器行为方法中的注释信息加载到"Swagger/index.html"页面中的控件器行为方法进行渲染显示。

    //注意:如果不在“*.csproj”文件中启用true配置,下面语句会出现逻辑异常。

    options.IncludeXmlComments(_xmlFilePath, true);

});

var app = builder.Build();

//把自定义管道中间中集成到.Net(Core)框架内置管道中,解决vue/uni-app前端项目(Cors)访问当前后端项目时,浏览器或App中出现的异常:

//    1“has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.”

//    2“has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.”

app.UseMiddleware<CorsMiddleware>();

//注意:在IIS部署时必须把下面两个管道中间件从“if (app.Environment.IsDevelopment())”取出,否则;“http://localhost:8090/Swagger/index.html”页面会出现“404”错误。

app.UseSwagger();

app.UseSwaggerUI();

//该自定义管道中间件设定/Swagger/index.html为默认启动页面。

//注意:在IIS部署时如果不定义该自定义管道中间件“http://localhost:8090”页面会出现“404”错误,但“http://localhost:8090/Swagger/index.html”页面可用;

//如果定义该自定义管道中间件IIS部署后的“http://localhost:8090”页面会强制自动跳转到“http://localhost:8090/Swagger/index.html”页面,从而避免根路由页面中“404”错误的出现。

app.UseMiddleware<SwaggerHomeMiddleware>();

//“SwaggerHomeMiddleware”管道中间件的直接实现调用。

//app.Use(async (context, next) =>

//{

//    if (context.Request.Path == "/")

//    {

//        context.Response.Redirect("/Swagger/index.html");

//        return;

//    }

//    await next.Invoke();

//});

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

3 WebApi.Test.RoleTestModel

namespace WebApi.Test

{

    public record RoleTestModel

    {

        ///

        /// 【角色名】

        ///

        /// 摘要:

        ///     获取/设置1个指定的角色名。

        ///

        ///

        public string Name { get; set; }

        ///

        /// 【启用?】

        ///

        /// 摘要:

        ///     获取/设置1个值false(禁用)/true(默认值:启用),该值指示角色实体的1个指定实例是否处于启用状态。

        ///

        ///

        public bool IsActive { get; set; }

        ///

        /// 【备注】

        ///

        /// 摘要:

        ///     获取/设置1个指定角色的备注信息。

        ///

        ///

        public string Remark { get; set; }

    }

}

4 WebApi.Controllers.RoleController

using Core.Domain.Users;

using Data;

using Microsoft.AspNetCore.Mvc;

using Microsoft.EntityFrameworkCore;

using WebApi.Test;

namespace WebApi.Controllers

{

    ///

    /// 【角色Api控制器--类】

    ///

    ///

    /// 摘要:

    ///     通过该类中的方法成员,为前端角色页面提供Api方法和数据支撑。

    ///

    [Route("[controller]/[action]")]

    [ApiController]

    public class RoleController : ControllerBase

    {

        #region 拷贝构造方法与变量

        private readonly EFCoreContext _context;

        public RoleController(EFCoreContext context)

        {

            _context = context;

        }

        #endregion

        #region 方法

        ///

        /// 【获取角色列表--需权限】

        ///

        ///

        /// 摘要:

        ///     从角色表中获取角色实体的所有实例,并把这些实例存储到列表实例中。

        ///

        ///

        /// 返回:

        ///     列表实例,该实例存储着角色实体的所有实例。

        ///

        [HttpGet]

        public async Task<List<Role>> GetRoleListAsync()

        {

            return await _context.GetDbSet<Role>().ToListAsync();

        }

        /// name="role">角色实体的1个指定实例。

        ///

        /// 【添加角色--需权限】

        ///

        ///

        /// 摘要:

        ///     把角色实体1个指定实例持久化到持久化到角色表中。

        ///

        ///

        /// 返回:

        ///     角色实体的1个指定实例。

        ///

        [HttpPost]

        public async Task<Role> AddRoleAsync([FromBody] Role role)

        {

            await _context.GetDbSet<Role>().AddAsync(role);

            await _context.SaveChangesAsync();

            return role;

        }

        /// name="roleId">角色实体1个指定实例的长整型编号值。

        ///

        /// 【更新角色--需权限】

        ///

        ///

        /// 摘要:

        ///     通过1个指定的长整型编号值,对1个角色实体1个指定实例并持久化到角色表的指定行中。

        ///

        ///

        /// 返回:

        ///     角色实体的1个指定实例。

        ///

        [HttpPost]

        public async Task<Role> UpdateRoleAsync(long roleId)

        {

            Role _model = await _context.GetDbSet<Role>().SingleAsync(role => role.Id == roleId);

            _model.Remark = _model.Remark + "Update";

            _context.GetDbSet<Role>().Update(_model);

            await _context.SaveChangesAsync();

            return _model;

        }

        #endregion

        #region 方法--测试

        /// name="roleTestModel">角色测试模型的1个指定实例。

        ///

        /// 【添加角色(测试模型)--需权限】

        ///

        ///

        /// 摘要:

        ///     把角色实体1个指定实例持久化到持久化到角色表中(只是测试使用,可以被删除)

        ///

        ///

        /// 返回:

        ///     角色实体的1个指定实例。

        ///

        [HttpPost]

        public async Task<Role> AddRoleTestModelAsync([FromBody] RoleTestModel roleTestModel)

        {

            Role role = new Role() { Name = roleTestModel.Name, IsActive = roleTestModel.IsActive, Remark = roleTestModel.Remark };

            await _context.GetDbSet<Role>().AddAsync(role);

            await _context.SaveChangesAsync();

            return role;

        }

        #endregion

    }

}

5 IIS发布部署与调试注意

5.1 调试注意

5.1.1 使用“/Swagger/index.html”调试

5.1.1.1 通过角色模型记录实例调试

    在“/Swagger/index.html”页面中使用带有“[FromBody]”参数实例的Api方法进行调试时,如果参数实例的类型为:“RoleTestModel”,则可以直接直接执行该Api方法:“WebApi.Controllers.RoleController.AddRoleTestModelAsync”,如下图所示:

第4章 角色Api控件器的实现与调试_第1张图片

第4章 角色Api控件器的实现与调试_第2张图片

5.1.1.2 直接通过角色实体实例调试

第4章 角色Api控件器的实现与调试_第3张图片

第4章 角色Api控件器的实现与调试_第4张图片 

第4章 角色Api控件器的实现与调试_第5张图片 

5.1.1 使用“Postman”调试

第4章 角色Api控件器的实现与调试_第6张图片

 第4章 角色Api控件器的实现与调试_第7张图片

5.2 IIS发布部署注意

5.2.1 IIS发布部署依赖包

5.2.1.1 连接字符串必须使用“SQL Server身份认证”数据库连接方式

    重构“appsettings.json”文件

{

  "ConnectionStrings": {

    //Trusted_Connection=trueIntegrated Security=true/SSPI:“Windows凭据SQL Server进行身份验证,表示可以在不知道数据库用户名和密码的情况下时,依然可以连接SQL Server数据库。

    //"integrated":"security=true是通过“Windows身份认证SQL Server数据库进行身份验证,并与SQL Server数据库进行连接;表示可以在不知道数据库用户名和密码的情况下时,依然可以连接SQL Server数据库,如果integrated", "security=false","或者不写,表示一定要输入正确的数据库登录名和密码。": null

    //Persist Security Info:该配置只用于通过“SQL Server身份认证SQL Server数据库进行身份验证,并与SQL Server数据库进行连接;简单的理解为"ADO在数据库连接成功后是否保存密码信息"True表示保存,False表示不保存.ADO缺省为True(ADO.net缺省为False,未测试,根据参考资料上说的)

    //MultipleActiveResultSets:它允许在单个连接上执行多重的数据库查询或存储过程,目前只适用于Sql Server 2005及其以上版本;如果不用MultipleActiveResultSets ,则一般报错为sqldatareader未关闭,即需要关闭了之后才能打开另一个。

    //Trust Server Certificate:是否使用SSL证书和加密方式,对SQL Server数据库的连接字符串进行加密,该操作属性安全性配置,目前只适用于Sql Server 2005及其以上版本;

   // "SqlServerWindows": "Data Source=.;Initial Catalog=ShopDemo;Integrated Security=true;MultipleActiveResultSets=true;Trust Server Certificate=True"

    "SqlServerSQL": "Data Source=.;Initial Catalog=ShopDemo;Integrated Security=False;Persist Security Info=False;User ID=zz;Password=zz;MultipleActiveResultSets=true;Trust Server Certificate=True"

  },

  "Logging": {

    "LogLevel": {

      "Default": "Information",

      "Microsoft.AspNetCore": "Warning"

    }

  },

  "AllowedHosts": "*"

}

5.2.1.2 依赖包

    在WebApi启用项中添加依赖包:

    1、Microsoft.EntityFrameworkCore.Tools或Microsoft.EntityFrameworkCore.Design;其中Microsoft.EntityFrameworkCore.Tools依赖包包含Microsoft.EntityFrameworkCore.Desig依赖包,当前程序中使用Microsoft.EntityFrameworkCore.Tools依赖包。

    2、注意:这两个依赖包必须直接引用在WebApi启用项目中,而间接Data引用在项目中。

    3、IIS部署的具体操作见:“第1章 基于.Net(Core)框架Web程序的IIS部署发布_zhoujian_911的博客-CSDN博客_.net iis发布”。

5.2.2 IIS发布部署404错误页面解决方案

       在当前程序部署后,默认路由页会出现404错误,为了避免该错误必须把“SwaggerHomeMiddleware”自定义管道中间件集成到.Net内置义管道中间件,把默认路由页强制自动跳转到“/Swagger/index.html”,从而把默认路由页相对设定为了“/Swagger/index.html”。

       对以上功能更为具体实现和注释见:221220_001shopvue(布局设计完成)。

你可能感兴趣的:(一步一步前后端开发实现,.Net7,前后端分离,商城,后端)