第29章 axios路由在uView 中的CURD实现

1 WebApi.Domain.Customers.Role

namespace WebApi.Domain.Customers

{

    /// <summary>

    /// 【角色--类】

    /// <remarks>

    /// 摘要:

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

    /// </remarks>

    /// </summary>

    public class Role

    {

        #region 属性

        /// <summary>

        /// 【编号】

        /// <remarks>

        /// 摘要:

        ///     获取/设置所有实体实例的长整型编号值。

        /// </remarks>

        /// </summary>

        public long Id { get; set; }

        /// <summary>

        /// 【角色名】

        /// <remarks>

        /// 摘要:

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

        /// 说明:

        ///     不区分大小写且必须具有唯一性。

        /// </remarks>

        /// </summary>

        public string Name { get; set; }

        /// <summary>

        /// 【启用?】

        /// <remarks>

        /// 摘要:

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

        /// </remarks>

        /// </summary>

        public bool Active { get; set; }

        /// <summary>

        /// 【系统角色?】

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个值false(不是系统角色)/true(默认值:系统角色),该值指示角色实体的1个指定实例是否是系统角色。

        /// 说明:

        ///     名称不能被修改;不能被物理/逻辑删除;必须处于启用状态。

        /// </remarks>

        /// </summary>

        public bool IsSystemRole { get; set; }

        /// <summary>

        /// 【备注】

        /// <remarks>

        /// 摘要:

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

        /// </remarks>

        /// </summary>

        public string Remark { get; set; }

        #endregion

    }

}

2 WebApi.Data.EFCoreContext

using Microsoft.EntityFrameworkCore;

using WebApi.Domain.Customers;

namespace WebApi.Data

{

    /// <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.【领域】.【用户集】.【角色】实体与“[WebApi].[Role]”表之间的CURD的交互操作,并把这些数据存储到数据库设置实例中(内存)

        /// </remarks>

        public DbSet<Role> RoleDbSet { get; set; }

        #endregion

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

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

        /// <summary>

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

        /// </summary>

        /// <remarks>

        /// 摘要:

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

        /// </remarks>

        protected override void OnModelCreating(ModelBuilder builder)

        {

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

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

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

            builder.Entity<Role>().Property(role => role.Name).HasMaxLength(50);

            builder.Entity<Role>().Property(role => role.Remark).HasMaxLength(100);

            base.OnModelCreating(builder);

        }

        #endregion

    }

}

3 launchSettings.json

"https": {

      "commandName": "Project",

      "dotnetRunMessages": true,

      "launchBrowser": true,

      "launchUrl": "swagger",

      "applicationUrl": "https://localhost:7144;http://localhost:5083", //uView 内置路由不能通过该本机域名获取数据,“axios” 路由在浏览器中可以直获取数据,但在真/模拟机中不能获取数据。

      //.Netcore IISExpressHttps在默认情况下是使用“IIS Express Development Certificate”SSL证书对“localhost”本机域名进行安全认证的,

      //而该证书又不能对本机IP127.0.0.1(IPV4)/192.168.2.230(IPV4)/::1(IPV6)进行安全认证,

      //同时由于.Netcore IISExpressHttps已经使用了“IISExpress Development Certificate”SSL证书,所以通过“mkcert生成SSL证书再对.Netcore IISExpressHttps进行安全认证后也无效,

      //uView内置路由不能通过该本机域名获取数据,测试时不可以直接获取数据。

      //  uView 内置路由如果要想使用HTTPS协议进行测试,必须通过IIS部署实现,“axios” 路由在浏览器中可以直获取数据,在真/模拟机中也能获取数据。

      //"applicationUrl": "https://127.0.0.1:7144",

      //"applicationUrl": "https://192.168.1.100:7144",

      "environmentVariables": {

        "ASPNETCORE_ENVIRONMENT": "Development"

      }

    },

4 WebApi.Controllers.WeatherForecastController

using Microsoft.AspNetCore.Mvc;

using WebApi.Data;

using WebApi.Domain.Customers;

namespace WebApi.Controllers

{

    [ApiController]

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

    public class WeatherForecastController : ControllerBase

    {

        private static readonly string[] Summaries = new[]

        {

            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"

        };

        private readonly ILogger<WeatherForecastController> _logger;

        private readonly EFCoreContext _eFCoreContext;

        public WeatherForecastController(ILogger<WeatherForecastController> logger,

            EFCoreContext eFCoreContext)

        {

            _logger = logger;

            _eFCoreContext = eFCoreContext;

        }

        [HttpGet]

        public IEnumerable<WeatherForecast> 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();

        }

        #region CURD

        [HttpGet]

        public List<Role> RoleList(long? id=null)

        {

            if(id==null || id==0)

                return _eFCoreContext.RoleDbSet.ToList();

            return _eFCoreContext.RoleDbSet.Where(r=>r.Id==id).ToList();

        }

        [HttpPost]

        public Role RolePost([FromBody] Role role)

        {

            //return null;//测试参数

            _eFCoreContext.RoleDbSet.Add(role);

            _eFCoreContext.SaveChanges();

            return role;

        }

        [HttpPut]

        public Role RolePut([FromBody] Role role)

        {

            //return null;//测试参数

               Role _role = _eFCoreContext.RoleDbSet.FirstOrDefault(entity => entity.Id ==role.Id);

              _role.Name = role.Name;

              _role.IsSystemRole = role.IsSystemRole;

              _role.Active = role.Active;

              _role.Remark = role.Remark;

              _eFCoreContext.RoleDbSet.Update(_role);

              _eFCoreContext.SaveChanges();

              return _role;

        }

        [HttpDelete]

        public bool RoleDelete(long id)

        {

            //return null;//测试参数

             Role _role = _eFCoreContext.RoleDbSet.FirstOrDefault(entity => entity.Id ==id);

               _eFCoreContext.RoleDbSet.Remove(_role);

               _eFCoreContext.SaveChanges();

            return true;

            //return _role;

        }

        [HttpDelete]

        public bool RoleDeleteSelected([FromBody] ICollection<long> selectedIds)

        {

            //return null;//测试参数

            var entries =  _eFCoreContext.RoleDbSet.Where(entry => selectedIds.Contains(entry.Id)).ToList();

            _eFCoreContext.RoleDbSet.RemoveRange(entries);

            _eFCoreContext.SaveChanges();

            return true;

        }

        /*  [HttpDelete]

          public Role RoleDeleteSelected(string selectedIds)

          {

              return null;//测试参数

          }*/

        #endregion CURD

    }

}

5 pages\role\AxiosLocalhostRouter\AxiosLocalhostRouter.vue

<template>

    <view class="content">

        <u-button type="primary" @click="RoleAllById()">axios.get路由通过参数获取数据</u-button>

        <u-button type="success" @click="RolePost()">axios.post路由添加数据</u-button>

        <u-button type="info" @click="RolePut()">axios.put路由修改数据</u-button>

        <u-button type="error" @click="RoleDelete()">axios.delete路由删除单个实例数据</u-button>

        <u-button type="warning" @click="RoleDeleteSelected()">axios.delete路由删除多个实例数据</u-button>

        <u-table>

            <u-tr>

                <u-th>编号</u-th>

                <u-th>角色名</u-th>

                <u-th>状态</u-th>

                <u-th>系统角色</u-th>

                <u-th>备注</u-th>

            </u-tr>

            <u-tr v-for="(item, index) in list" :key="index">

                <u-td>{{ item.id }}</u-td>

                <u-td>{{ item.name }}</u-td>

                <u-td>{{ item.active }}</u-td>

                <u-td>{{ item.isSystemRole }}</u-td>

                <u-td>{{ item.remark }}</u-td>

            </u-tr>

        </u-table>

    </view>

</template>

<script>

    import axios from 'axios';

    //import qs from 'qs';

    export default {

        data() {

            return {

                list: [],

            }

        },

        async onLoad() {

            //内置路由CURD测试

            await this.RoleAll();

        },

        methods: {

            async RoleAll() {

                this.list = await (await axios.get('https://localhost:7144/WeatherForecast/RoleList')).data;

                //console.log(".NeCore--HTTPS: localhost:7144--可用域名示例:", this.list);

            },

            async RoleAllById() {

                let roleId = {

                    id: 3,

                };

                //axios.get路由必须包含参数关键字:params,定义格式形如:{params: roleId}

                this.list = await (await axios.get('https://localhost:7144/WeatherForecast/RoleList', {

                    params: roleId

                })).data;

                //console.log(".NeCore--HTTPS: localhost:7144--可用域名示例:", this.list);

            },

            async RolePost() {

                let role = {

                    "name": "RolePost--axios.post路由",

                    "active": true,

                    "isSystemRole": true,

                    "remark": "axios.post路由测试"

                };

                //axios.post路由中的参数必须被“JSON.stringify”方法序列化,且必须包含“headers”参数实例,否则会出现错误:“AxiosError {message: 'Request failed with status code 415'”

                /* “headers” 参数实例, 可以直接定义在axios.post路由方法中(只对当前api方法有效)

                    “ headers” 参数实例前端的拦截中进行定义(全局,即所有api方法有效)

                                config = {

                                    baseUrl: '', // 请求的本域名

                                    method: 'POST',

                                    // 设置为json,返回后会对数据进行一次JSON.parse()

                                    dataType: 'json',

                                    showLoading: true, // 是否显示请求中的loading

                                    loadingText: '请求中...', // 请求loading中的文字提示

                                    loadingTime: 800, // 在此时间内,请求还没回来的话,就显示加载中动画,单位ms

                                    originalData: false, // 是否在拦截器中返回服务端的原始数据

                                    loadingMask: true, // 展示loading的时候,是否给一个透明的蒙层,防止触摸穿透

                                    // 配置请求头信息

                                    header: {

                                        'content-type': 'application/json;charset=UTF-8'

                                    },

                                }“

                    headers” 参数实例在定义在后端(全局,即所有api方法有效):

                                    if (context.Request.Headers.ContainsKey(CorsConstants.Origin)) {

                                        //解决在前端通过“axios.post”方式调用后端POST-API,如果前端“axios.post”路由没有加载“headers”参数实例,下1行语句中的配置,否则“axios.post”方法,访问后端的POST-API,否则会出现:"HTTP:415"错误。

                                        context.Request.ContentType = "application/json";

               

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

                                        //“' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.”

                                        if (context.Request.Method.Equals("OPTIONS")) {

                                            context.Response.StatusCode = StatusCodes.Status200OK;

                                            return;

                                        }

                                    }

                */

                await axios.post('https://localhost:7144/WeatherForecast/RolePost',

                    JSON.stringify(role), {

                        headers: {

                            "Content-Type": "application/json"

                        }

                    }

                );

                await this.RoleAll();

            },

            async RolePut() {

                let role = {

                    "id": 2,

                    "name": "RolePut--axios.put路由",

                    "active": false,

                    "isSystemRole": false,

                    "remark": "axios.put路由测试"

                };

                //axios.put路由中的参数必须被“JSON.stringify”方法序列化,且必须包含“headers”参数实例,否则会出现错误:“AxiosError {message: 'Request failed with status code 415'”

                /* “headers” 参数实例, 可以直接定义在axios.put路由方法中(只对当前api方法有效)

                    “ headers” 参数实例前端的拦截中进行定义(全局,即所有api方法有效)

                                config = {

                                    baseUrl: '', // 请求的本域名

                                    method: 'POST',

                                    // 设置为json,返回后会对数据进行一次JSON.parse()

                                    dataType: 'json',

                                    showLoading: true, // 是否显示请求中的loading

                                    loadingText: '请求中...', // 请求loading中的文字提示

                                    loadingTime: 800, // 在此时间内,请求还没回来的话,就显示加载中动画,单位ms

                                    originalData: false, // 是否在拦截器中返回服务端的原始数据

                                    loadingMask: true, // 展示loading的时候,是否给一个透明的蒙层,防止触摸穿透

                                    // 配置请求头信息

                                    header: {

                                        'content-type': 'application/json;charset=UTF-8'

                                    },

                                }“

                    headers” 参数实例在定义在后端(全局,即所有api方法有效):

                                    if (context.Request.Headers.ContainsKey(CorsConstants.Origin)) {

                                        //解决在前端通过“axios.post”方式调用后端POST-API,如果前端“axios.post”路由没有加载“headers”参数实例,下1行语句中的配置,否则“axios.post”方法,访问后端的POST-API,否则会出现:"HTTP:415"错误。

                                        context.Request.ContentType = "application/json";

               

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

                                        //“' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.”

                                        if (context.Request.Method.Equals("OPTIONS")) {

                                            context.Response.StatusCode = StatusCodes.Status200OK;

                                            return;

                                        }

                                    }

                */

                await axios.put('https://localhost:7144/WeatherForecast/RolePut',

                    JSON.stringify(role), {

                        headers: {

                            "Content-Type": "application/json"

                        }

                    }

                );

                await this.RoleAll();

            },

            async RoleDelete() {

                let roleId = {

                    id: 1

                };

                //axios.delete路由必须包含参数关键字:params,定义格式形如:{params: roleId}

                await axios.delete('https://localhost:7144/WeatherForecast/RoleDelete', {

                    params: roleId

                });

                await this.RoleAll();

            },

            async RoleDeleteSelected() {

                let idArray = [2, 3, 4];

               

                /* //后端控制器行为使用字符串类型参数实例,例如:[HttpDelete] public Role RoleDeleteSelected(string selectedIds)

                let ids = {

                    selectedIds: idArray.join()

                };

                //axios.delete路由必须包含参数关键字:params,定义格式形如:{params: selectedIds}

                await axios.delete('https://localhost:7144/WeatherForecast/RoleDeleteSelected',{params: ids}); */

               

                //后端控制器行为使用列表参数实例,例如:[HttpDelete] public IActionResult DeleteArray([FromBody] ICollection<long> selectedIds)

                //注意:如果后端控制器行为使用列表参数实例,axios.delete路由的参数关键字为“data”,而非“params”,否则会出现“415”错误。

                await axios.delete('https://localhost:7144/WeatherForecast/RoleDeleteSelected', { data: idArray });

               

                await this.RoleAll();

            },

        }

    }

</script>

<style lang="scss" scoped>

    .content {

        display: flex;

        flex-direction: column;

        align-items: center;

        justify-content: center;

        padding: 40rpx;

    }

    .logo {

        height: 200rpx;

        width: 200rpx;

        margin-top: 100rpx;

        margin-left: auto;

        margin-right: auto;

        margin-bottom: 50rpx;

    }

    .text-area {

        display: flex;

        justify-content: center;

    }

    .title {

        font-size: 28rpx;

        color: $u-content-color;

    }

    .button-demo {

        margin-top: 80rpx;

    }

    .link-demo {

        margin-top: 80rpx;

    }

</style>

对以上功能更为具体实现和注释见:230630_030WebApi(axios路由在uView 中的CURD实现)

230630_003uView_default(axios路由在uView 中的CURD实现)

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值