第2章 Vue服务器(后)端Swagger定义实现与发布部署

在基于.Net(Core)6框架开发的程序中,是通过Swagger中间件来实现前后端的分离和之间数据的相互交互操作的,即vue前端项目与相对应的.Net(Core)6后端项目分离实现核心是Swagger中间件,且该中间件的配置和定义实现都在.Net(Core)6后端项目中进行,本章讲述怎样通过Swagger中间件构建,能够让与相对应vue前端项目进行渲染显示的后端项目。

  Vusal studio 构建支持Swagger中间件项目有两种方式:1、一种是直接通过“ASP.NET Core Web API”模板直接构建,该模板会直接包含Swagger中间件,2、另一种是通过“ASP.NET Core MVC(模型-视图-控制器)”模板,间接构建,由于该模板不接包含Swagger中间件,所以需要通过特定的配置定义以使项目包含Swagger中间件,本人为了程序的开发效率,通过第2种方式使项目包含Swagger中间件。如果下图所示:

   

在使用“ASP.NET Core MVC(模型-视图-控制器)”模板,间接构建项目时,由于该模板不接包含Swagger中间件,所以必须先通过Nugut引用Swagger中间件,使用构建项目包含Swagger中间件,如果下图所示:

1 数据交换类EFCoreContext

/// <summary>

    /// 【EFCore上下文】

    /// </summary>

    /// <remarks>

    /// 摘要:

    ///     获取/设置学生实体的数据库设置实例,用于实现指定实体与数据库指定表的CURD操作。

    /// </remarks>

    public class EFCoreContext : DbContext

    {

        #region 拷贝构造方法

        /// <summary>

        /// 【拷贝构造方法】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///    基类构造通过该构造方法中的参数实例,连接到指定数据库(SQL Server)数据库软件中数据库。

        /// </remarks>

        public EFCoreContext(DbContextOptions<EFCoreContext> options) : base(options)

        {

            //如果(SQL Server)数据库软件中没有指定的数据库, 当通过Code First模式时,在第1次生成数据库时,则通过下1行语句结合数据库连接字符串,在(SQL Server)数据库软件中生成指定的数据库数据库、表、字段和约束规则。

            Database.EnsureCreated();

            /*

            如果(SQL Server)数据库软件中没有指定的数据库, 当通过Code First模式时,在第1次生成数据库时,则也通过下行执行迁移和更新命令行的结合数据库连接字符串,在(SQL Server)数据库软件中生成指定的数据库数据库、表、字段和约束规则。

            Add-Migration Initialize(Initialize:自动生成的迁移类名,这里特指:20220803125612_Initialize.cs):

            Update-Database Initialize(通过自动生成的迁移类中的定义,自动在指定的数据库软件中生成指定的数据库、表、字段和约束规则)

             */

        }

        #endregion

        #region 属性

        /// <summary>

        /// 【角色数据库设置】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///     获取/设置角色实体的数据库设置实例,用于实现当前程序【Web】.【领域】.【用户集】.【角色】实体与“[UserVue].[SysRole]”表之间的CURD的交互操作,并把这些数据存储到数据库设置实例中(内存)。

        /// </remarks>

        public DbSet<SysRole> SysRoleDbSet { get; set; }

        /// <summary>

        /// 【用户数据库设置】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///      获取/设置用户实体的数据库设置实例,用于实现当前程序【Web】.【领域】.【用户集】.【用户】实体与“[UserVue].[SysUser]”表之间的CURD的交互操作,并把这些数据存储到数据库设置实例中(内存)。

        /// </remarks>

        public DbSet<SysUser> SysUserDbSet { get; set; }

        /// <summary>

        /// 【菜单数据库设置】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///      获取/设置菜单实体的数据库设置实例,用于实现当前程序【Web】.【领域】.【用户集】.【菜单】实体与“[UserVue].[SysMenu]”表之间的CURD的交互操作,并把这些数据存储到数据库设置实例中(内存)。

        /// </remarks>

        public DbSet<SysMenu> SysMenuDbSet { get; set; }

        /// <summary>

        /// 【控件器行为方法数据库设置】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///      获取/设置控件器行为方法实体的数据库设置实例,用于实现当前程序【Web】.【领域】.【用户集】.【控件器行为方法】实体与“[UserVue].[SysAction]”表之间的CURD的交互操作,并把这些数据存储到数据库设置实例中(内存)。

        /// </remarks>

        public DbSet<SysAction> SysActionDbSet { get; set; }

        /// <summary>

        /// 【用户角色映射数据库设置】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///      获取/设置用户角色映射实体的数据库设置实例,用于实现当前程序【Web】.【领域】.【用户集】.【用户角色映射】实体与“[UserVue].[SysUserRole]”表之间的CURD的交互操作,并把这些数据存储到数据库设置实例中(内存)。

        /// </remarks>

        public DbSet<SysUserRole> SysUserRoleDbSet { get; set; }

        /// <summary>

        /// 【角色菜单映射】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///     获取/设置角色菜单映射实体的数据库设置实例,用于实现当前程序【Web】.【领域】.【用户集】.【角色菜单映射】实体与“[UserVue].[SysRoleMenu]”表之间的CURD的交互操作,并把这些数据存储到数据库设置实例中(内存)。

        /// </remarks>

        public DbSet<SysRoleMenu> SysRoleMenuDbSet { get; set; }

        #endregion

        #region 方法--私有/保护--覆写

        ///<param name="builder">模型生成器实例,用于把当前程序中实体和属性所定义的约束规则,映射到数据库指定表及其字段上。</param>

        /// <summary>

        /// 【模型生成执行...】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///     该方法把当前程序中实体和属性所定义的约束规则,映射到数据库指定表及其字段上。

        /// </remarks>

        protected override void OnModelCreating(ModelBuilder builder)

        {

            //角色表约束规则,映射定义。

            builder.Entity<SysRole>().ToTable(nameof(SysRole));

            builder.Entity<SysRole>().HasKey(role => role.Id);

            builder.Entity<SysRole>().Property(role => role.RoleName).HasMaxLength(50);

            builder.Entity<SysRole>().Property(role => role.Description).HasMaxLength(100);

            builder.Entity<SysRole>().Property(role => role.CreateBy).HasMaxLength(50);

            //用户表约束规则,映射定义。

            builder.Entity<SysUser>().ToTable(nameof(SysUser));

            builder.Entity<SysUser>().HasKey(user => user.Id);

            builder.Entity<SysUser>().Property(user => user.LoginName).HasMaxLength(50);

            builder.Entity<SysUser>().Property(user => user.LoginPWD).HasMaxLength(200);

            builder.Entity<SysUser>().Property(user => user.RealName).HasMaxLength(200);

            builder.Entity<SysUser>().Property(user => user.Remark).HasMaxLength(2000);

            builder.Entity<SysUser>().Property(user => user.Addr).HasMaxLength(200);

            builder.Entity<SysUser>().Property(user => user.CreateBy).HasMaxLength(50);

            //菜单表约束规则,映射定义。

            builder.Entity<SysMenu>().ToTable(nameof(SysMenu));

            builder.Entity<SysMenu>().HasKey(menu => menu.Id);

            builder.Entity<SysMenu>().Property(menu => menu.Name).HasMaxLength(50);

            builder.Entity<SysMenu>().Property(menu => menu.Icon).HasMaxLength(100);

            builder.Entity<SysMenu>().Property(menu => menu.Description).HasMaxLength(200);

            builder.Entity<SysMenu>().Property(menu => menu.CreateBy).HasMaxLength(50);

            builder.Entity<SysMenu>().Property(menu => menu.ModifyBy).HasMaxLength(50);

            //通过该映射定义,去除菜单表与控制器行为方法表之间的级联约束规则。

            builder.Entity<SysMenu>().Ignore(menu => menu.SysActions);

            //控制器行为方法表约束规则,映射定义。

            builder.Entity<SysAction>().ToTable(nameof(SysAction));

            builder.Entity<SysAction>().HasKey(action => action.Id);

            builder.Entity<SysAction>().Property(action => action.Name).HasMaxLength(50);

            builder.Entity<SysAction>().Property(action => action.LinkUrl).HasMaxLength(100);

            builder.Entity<SysAction>().Property(action => action.Controller).HasMaxLength(100);

            builder.Entity<SysAction>().Property(action => action.Action).HasMaxLength(100);

            builder.Entity<SysAction>().Property(action => action.Code).HasMaxLength(10);

            builder.Entity<SysAction>().Property(action => action.Description).HasMaxLength(200);

            builder.Entity<SysAction>().Property(action => action.CreateBy).HasMaxLength(50);

            builder.Entity<SysAction>().Property(action => action.ModifyBy).HasMaxLength(50);

            //通过该映射定义,去除菜单表与控制器行为方法表之间的级联约束规则。

            builder.Entity<SysAction>().Ignore(action => action.SysMenu);

            //用户角色映射表约束规则,映射定义。

            builder.Entity<SysUserRole>().ToTable(nameof(SysUserRole));

            builder.Entity<SysUserRole>().HasKey(userRole => userRole.Id);

            builder.Entity<SysUserRole>().Property(userRole => userRole.CreateBy).HasMaxLength(50);

            builder.Entity<SysUserRole>().Property(userRole => userRole.ModifyBy).HasMaxLength(50);

            //角色菜单映射表约束规则,映射定义。

            builder.Entity<SysRoleMenu>().ToTable(nameof(SysRoleMenu));

            builder.Entity<SysRoleMenu>().HasKey(roleMenu => roleMenu.Id);

            builder.Entity<SysRoleMenu>().Property(roleMenu => roleMenu.CreateBy).HasMaxLength(50);

            builder.Entity<SysRoleMenu>().Property(roleMenu => roleMenu.ModifyBy).HasMaxLength(50);

            base.OnModelCreating(builder);

        }

        #endregion

    }

2 SysRole

   /// <summary>

    /// 【角色--类】

    /// </summary>

    /// <remarks>

    /// 摘要:

    ///     通过该实体类及其属性成员,用于实现当前程序【Web】.【领域】.【用户集】.【角色】实体与“[UserVue].[SysRole]”表之间的CURD的交互操作,并把这些数据存储到数据库设置实例中(内存)。

    /// </remarks>

    public class SysRole

    {

        /// <summary>

        /// 【编号】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///     获取/设置角色实体1个指定实例的整型编号值。

        /// </remarks>

        public int Id { get; set; }

        /// <summary>

        /// 【角色名称】

        /// </summary>

        /// <remarks>

        /// 摘要:

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

        /// </remarks>

        public string RoleName { get; set; }

        /// <summary>

        /// 【描述】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个指定角色的描述信息。

        /// </remarks>

        public string Description { get; set; }

        /// <summary>

        /// 【排序】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个指定角色实例在所有角色实例中的排序顺序整型值。

        /// </remarks>

        public int OrderSort { get; set; }

        /// <summary>

        /// 【启用?】

        /// </summary>

        /// <remarks>

        /// 摘要:

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

        /// </remarks>

        public bool Enabled { get; set; }

        /// <summary>

        /// 【已经删除?】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个值false(默认值,未逻辑删除)/true(已经处于逻辑删除状态),该值指示角色实体1个指定实例是否已经处于逻辑删除状态。

        /// </remarks>

        public bool? IsDeleted { get; set; }

        /// <summary>

        /// 【创建者编号】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///     获取/设置创建角色实体1个指定实例的创建者的整型编号值,即用户实体1个指定实例的整型编号值。

        /// </remarks>

        public int? CreateId { get; set; }

        /// <summary>

        /// 【创建者名称】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///     获取/设置创建角色实体1个指定实例的创建者的名称,即1个指定用户的名称。

        /// </remarks>

        public string CreateBy { get; set; }

        /// <summary>

        /// 【创建时间】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///     获取/设置角色实体1个指定实例第1次被持久化到角色表中的时间。

        /// </remarks>

        public DateTime? CreateTime { get; set; } = DateTime.Now;

        /// <summary>

        /// 【修改者编号】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///     获取/设置角色实体1个指定实例最后1次被修改后,修改者的整型编号值,即用户实体1个指定实例的整型编号值。

        /// </remarks>

        public int? ModifyId { get; set; }

        /// <summary>

        /// 【修改者名称】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///     获取/设建角色实体1个指定实例最后1次被修改后,修改者的名称,即1个指定用户的名称。

        /// </remarks>

        public string ModifyBy { get; set; }

        /// <summary>

        /// 【修改时间】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///     获取/设置角色实体1个指定实例最后1次被修改后,持久化到角色表中的时间。

        /// </remarks>

        public DateTime? ModifyTime { get; set; } = DateTime.Now;

    }

3 模型类

3.1 PageModel

  ///<typeparam name="T">泛型类型实例(1个指定类的类型实例)。</typeparam>

    /// <summary>

    /// 【页模型】

    /// </summary>

    /// <remarks>

    /// 摘要:

    ///     通过该类的属性成员对指定实体中的所有实例进行存储,这些实例数据为页面的渲染显示提供数据支撑。

    /// </remarks>

    public class PageModel<T>

    {

        #region 拷贝构造方法

        /// <summary>

        /// 【拷贝构造方法】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///     通过该拷贝构造方法为该类中的列表属性成员分配内存空间。

        /// </remarks>

        public PageModel(List<T> dataList)

        {

            data = dataList;

        }

        #endregion

        #region 属性

        /// <summary>

        /// 【数据】

        /// <remarks>

        /// 摘要:

        ///     获取/设置列表实例,该实例用于存储指定实体中的所有实例。

        /// </remarks>

        /// </summary>

        public List<T> data { get; set; }

        #endregion

    }

3.2 MessageModel

///<typeparam name="T">泛型类型实例(1个指定类的类型实例)。</typeparam>

    /// <summary>

    /// 【消息模型】

    /// </summary>

    /// <remarks>

    /// 摘要:

    ///      通过该类的属性成员对指定实体中的所有实例进行存储,和指定控制器行方法的执行结果信息行存储,这些实例数据和执行结果信息行为页面的渲染显示提供数据支撑。

    /// </remarks>

    public class MessageModel<T>

    {

        #region 属性

        /// <summary>

        /// 【 状态】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///     获取/设置指定控制器行方法的执行结果状态整值,默认值:200(执行成功状态)。

        /// </remarks>

        public int status { get; set; } = 200;

        /// <summary>

        /// 【成功?】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个值false(默认值,执行失败)/true(执行成功),该值指示指定控制器行方法的执行结果状态。

        /// </remarks>

        public bool success { get; set; } = false;

        /// <summary>

        /// 【信息】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///     获取/设置指定控制器行方法的执行结果信息。

        /// </remarks>

        public string msg { get; set; } = "";

        /// <summary>

        /// 【应答】

        /// <remarks>

        /// 摘要:

        ///     获取/设置列表实例,该实例用于存储指定实体中的所有实例。

        /// </remarks>

        /// </summary>

        public T response { get; set; }

        #endregion

    }

4 通过定义配置使项目支持Swagger

4.1 通过Program.cs中的定义支持Swagger

4.1.1 “*.csproj”配置

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>

    <TargetFramework>net6.0</TargetFramework>

    <Nullable>annotations</Nullable>

    <ImplicitUsings>enable</ImplicitUsings>

     <!--GenerateDocumentationFile配置:从"Web.xml"文件中获取指定的注释信息,为在“/Swagger/index.html”页面中显示指定控件器行为方法的相关作用信息,提供支撑。

     注意:启用GenerateDocumentationFile配置,所有的定义都必须注释,否则会出现语法警告信息。-->

     <GenerateDocumentationFile>true</GenerateDocumentationFile>

  </PropertyGroup>

  <ItemGroup>

    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.9">

      <PrivateAssets>all</PrivateAssets>

      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

    </PackageReference>

    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.9" />

    <PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />

  </ItemGroup>

</Project>

4.1.2 内置依赖注入定义支持Swagger

//通过AddSwaggerGen依赖注入中间方法,把Swagger中间件注入到.Net(Core)6框架默认容器中。

builder.Services.AddSwaggerGen(c =>

{

    c.SwaggerDoc("v1", new OpenApiInfo { Title = "EmptyTemplate.Api", Version = "v1" });

    //从"Web.xml"文件中获取指定的注释信。

    var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";

    var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);

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

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

    c.IncludeXmlComments(xmlPath, true);

});

4.1.3 内置管道集成支持Swagger

//通过UseSwagger、UseSwaggerUI管道中间方法,把Swagger中间件集成到.Net(Core)6框架中,以使用当前程序能够在前台页面能够以“Swagger”方式进行后台的相关操作(例如:“/Swagger/index.html”)。

app.UseSwagger();

app.UseSwaggerUI();

5 API控制器与控制器行为方法(RoleController)定义

/// <summary>

    /// 角色管理

    /// </summary>

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

    [ApiController]

    public class RoleController : Controller

    {

        #region 拷贝构造方法

        /// <summary>

        /// 【EFCore上下文实例】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///     声明角色实体的数据库设置实例, 该实例通过EFCore数据交换中间件实现当前程序与指定数据库之间的CURD操作。

        /// </remarks>

        private readonly EFCoreContext _context;

        ///<param name="context">模型生成器实例,用于把当前程序中实体和属性所定义的约束规则,映射到数据库指定表及其字段上。</param>

        /// <summary>

        /// 【拷贝构造方法】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///    基类构造通过该构造方法中的参数实例,连接到指定数据库(SQL Server)数据库软件中数据库。

        /// </remarks>

        public RoleController(EFCoreContext context)

        {

            _context = context;

        }

        #endregion

        #region CRUD操作

        /// <summary>

        /// 【获取所有角色】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///     以异步方式,通过该方法获取角色表中的所有角色实例,并把所有角色实例及其操作结果存储到消息模型实例中,为页面的渲染显示提供数据支撑。

        /// </remarks>

        /// <returns>

        ///     消息模型实例,为页面的渲染显示提供数据支撑。

        /// </returns>

        [HttpGet]

        public async Task<MessageModel<PageModel<SysRole>>> Get()

        {

            var data = await _context.SysRoleDbSet.ToListAsync();

            var d1 = new PageModel<SysRole>(data);

            return new MessageModel<PageModel<SysRole>>()

            {

                msg = "获取成功",

                success = true,

                response = d1,

            };

        }

        /// <summary>

        /// 【添加角色】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///     以异步方式,通过该方法获把1个指定的角色实例持久化到数据库的角色表中,并把该角色实例及其操作结果存储到消息模型实例中,以为页面的渲染显示提供数据支撑。

        /// </remarks>

        /// <returns>

        ///     消息模型实例,为页面的渲染显示提供数据支撑。

        /// </returns>

        [HttpPost]

        public async Task<MessageModel<string>> Post([FromBody] SysRole role)

        {

            await _context.SysRoleDbSet.AddRangeAsync(role);

            await _context.SaveChangesAsync();

            var m = role;

            var data = new MessageModel<string>();

            data.success = m.Id > 0;

            if (data.success)

            {

                data.response = m.Id.ToString();

                data.msg = "添加成功";

            }

            return data;

        }

        #endregion

    }

注意:必须在控制器类上定义标记:  [Route("[controller]/[action]")]、[ApiController],能够实现前端项目对后端项目的交互操作,同时控制器类行为方法返回的是的指定模型类的实例数据,而非IactionResult实例

6配置与定义跨域(Cors)操作

    跨域(Cors)操作的目的是:后端“appsettings.json”文件中配置的域名及其端口集中,是否包含有vue前端项目的访问域名及其端口,如果配置域名及其端口集中,不包含后端项目的访问域名及其端口,且在“Program.cs” 文件进行了限定定义,那么vue前端是不能与.Net(Core)6后端项目进行交互操作的。

6.1 在appsettings.json中配置跨域(Cors)交互限定

//  跨域(Cors)配置的域名及其端口集,该端口集中是否包含有vue前端项目的访问域名及其端口,如果配置域名及其端口集中,不包含后端项目的访问域名及其端口,

    //且在“Program.cs” 文件进行了限定定义,那么vue前端是不能与.Net(Core)6后端项目进行交互操作的。

    "Cors": {

        "PolicyName": "CorsIpAccess", //vue前端是不能与.Net(Core)6后端项目进行交互操作的策略名称。

        "EnableAllIPs": false, //当为true时,开放所有IP均可访问。    

        //跨域(Cors)配置的域名及其端口集,用来限定vue前端的访问及其交互操作。

        "IPs": "http://localhost:8080,http://localhost:8081,,http://localhost:8082,,http://localhost:8083,http://localhost:8021"

    },

6.2 在Program.cs中定义跨域(Cors)交互限定

6.2.1 内置依赖注入定义跨域(Cors)交互限定

//通过AddCors依赖注入中间方法,把Cors(跨域)中间件注入到.Net(Core)6框架默认容器中。

//Cors(跨域)操作是如果“appsettings.json”文件中配置的所有域名中,至少有1个与“vue”前台项目相匹配域名时,则“vue”前台项目就从当前后台项目中获取相关数据,从而实现页面的渲染显示。

builder.Services.AddCors(c =>

{

    //限定“appsettings.json”文件中配置的所有域名中,至少有1个与“vue”前台项目相匹配域名,才能上“vue”前台项目就从当前后台项目中获取相关数据,从而实现页面的渲染显示。

    if (!Convert.ToBoolean(builder.Configuration["Cors:EnableAllIPs"]))

    {

        c.AddPolicy(builder.Configuration["Cors:PolicyName"],

            policy =>

            {

                policy

                .WithOrigins(builder.Configuration["Cors:IPs"].Split(','))

                .AllowAnyHeader()

                .AllowAnyMethod();

            });

    }

    else

    {

        //不做限定,“vue”前台项目能够直接从当前后台项目中获取相关数据,从而实现页面的渲染显示

        c.AddPolicy(builder.Configuration["Cors:PolicyName"],

            policy =>

            {

                policy

                .SetIsOriginAllowed((host) => true)

                .AllowAnyMethod()

                .AllowAnyHeader()

                .AllowCredentials();

            });

    }

});

6.2.2 内置管道集成支持跨域(Cors)交互限定

app.UseCors(app.Configuration["Cors:PolicyName"]);

7 发布与部署

    .Net(Core)6后端项目必须在最后进行发布部署操作,并通过IIS配置相应的网站后,才能实现vue前端项目与后端项目中的数据进行交互操作,并在vue前端项目中进行渲染显示。关于后端项目必须在最后进行发布部署操作,并通过IIS配置相应的网站,请查看本人的文章:“https://blog.csdn.net/zhoujian_911/article/details/126864660”。

    对以上功能更为具体实现和注释见:22-09-22-02_UserVue(Vue服务器(后)端Swagger定义实现与发布部署)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值