七天.NET 8操作SQLite入门到实战 - (2)第七天Blazor班级管理页面编写和接口对接

本文主要讲解关于七天.NET 8操作SQLite入门到实战 - (2)第七天Blazor班级管理页面编写和接口对接相关内容,让我们来一起学习下吧!

前言

上一章节我们引入BootstrapBlazor UI组件完成了EasySQLite后台界面的基本架子的搭建,本章节的主要内容是Blazor班级管理页面编写和接口对接。

七天.NET 8 操作 SQLite 入门到实战详细教程

  • 第一天 SQLite 简介
  • 第二天 在 Windows 上配置 SQLite 环境
  • 第三天 SQLite 快速入门
  • 第四天 EasySQLite 前后端项目框架搭建
  • 第五天引入 SQLite-net ORM 并封装常用方法
  • 第六天后端班级管理相关接口完善和Swagger自定义配置
  • 第七天BootstrapBlazor UI组件库引入(1)

EasySQLite 项目源码地址

  • GitHub 地址:https://github.com/YSGStudyHards/EasySQLite

Blazor简介和快速入门

不熟悉Blazor的同学可以先看这篇文章大概了解一下。

全面的ASP.NET Core Blazor简介和快速入门

前端Table页面和接口对接代码

主要是常见Table的数据展示、数据添加、数据删除、数据修改等操作。

七天.NET 8操作SQLite入门到实战 - (2)第七天Blazor班级管理页面编写和接口对接

七天.NET 8操作SQLite入门到实战 - (2)第七天Blazor班级管理页面编写和接口对接

七天.NET 8操作SQLite入门到实战 - (2)第七天Blazor班级管理页面编写和接口对接

七天.NET 8操作SQLite入门到实战 - (2)第七天Blazor班级管理页面编写和接口对接

@page "/SchoolClass"@using Entity@using WebUI.Common@inject HttpClient _httpClient;<Table TItem="SchoolClass"       AutoGenerateColumns="true"       ShowToolbar="true"       IsMultipleSelect="true"       OnSaveAsync="@OnSaveAsync"       OnQueryAsync="@OnQueryAsync"       OnDeleteAsync="@OnDeleteAsync"       IsStriped="true"       IsBordered="true"       ShowSearch="true"       IsPagination="true"       ShowSearchText="true">    <TableColumns>        <TableColumn Sortable="true" Filterable="true" Searchable="true" @bind-Field="@context.ClassName" PlaceHolder="请输入班级名称" />        <TableColumn @bind-Field="@context.ClassID" IsVisibleWhenAdd="false" IsVisibleWhenEdit="false" />        <TableColumn @bind-Field="@context.CreateTime" IsVisibleWhenAdd="false" IsVisibleWhenEdit="false" />    </TableColumns>    <SearchTemplate>        <GroupBox Title="搜索条件">            <div class="row g-3 form-inline">                <div class="col-12 col-sm-6">                    <BootstrapInput @bind-Value="@context.ClassName" PlaceHolder="请输入班级名称" maxlength="50" ShowLabel="true" DisplayText="姓名" />                </div>            </div>        </GroupBox>    </SearchTemplate></Table>@code {    /// <summary>    /// 数据查询    /// </summary>    /// <param name="options">options</param>    /// <returns></returns>    private async Task<QueryData<SchoolClass>> OnQueryAsync(QueryPageOptions options)    {        var getClass = new List<SchoolClass>();        var getResults = await _httpClient.GetFromJsonAsync<ApiResponse<List<SchoolClass>>>("api/SchoolClass/GetClass").ConfigureAwait(false);        if (getResults.Success)        {            // 数据模糊过滤筛选            if (!string.IsNullOrWhiteSpace(options.SearchText))            {                getClass = getResults.Data.Where(x => x.ClassName.Contains(options.SearchText)).ToList();            }            else            {                getClass = getResults.Data.ToList();            }        }        //假分页        return await Task.FromResult(new QueryData<SchoolClass>()            {                Items = getClass.Skip((options.PageIndex - 1) * options.PageItems).Take(options.PageItems).ToList(),                TotalCount = getClass.Count()            });    }    /// <summary>    /// 模拟数据增加和修改操作    /// </summary>    /// <param name="studentInfo">studentInfo</param>    /// <param name="changedType">changedType</param>    /// <returns></returns>    public async Task<bool> OnSaveAsync(SchoolClass studentInfo, ItemChangedType changedType)    {        if (changedType.ToString() == "Update")        {            var addResult = await _httpClient.PutAsJsonAsync($"api/SchoolClass/UpdateClass/{studentInfo.ClassID}", studentInfo).ConfigureAwait(false);            if (UtilityBusiness.CheckResponse(addResult))            {                return await Task.FromResult(true);            }            else            {                return await Task.FromResult(false);            }        }        else if (changedType.ToString() == "Add")        {            var addResult = await _httpClient.PostAsJsonAsync("api/SchoolClass/CreateClass", studentInfo).ConfigureAwait(false);            if (UtilityBusiness.CheckResponse(addResult))            {                return await Task.FromResult(true);            }            else            {                return await Task.FromResult(false);            }        }        return await Task.FromResult(true);    }    /// <summary>    /// 数据删除    /// </summary>    /// <param name="items">items</param>    /// <returns></returns>    private async Task<bool> OnDeleteAsync(IEnumerable<SchoolClass> items)    {        var deleteSuccessNum = 0;        var schoolClassList = items.ToList();        foreach (var item in schoolClassList)        {            var delResult = await _httpClient.DeleteAsync($"api/SchoolClass/DeleteClass/{item.ClassID}").ConfigureAwait(false);            if (UtilityBusiness.CheckResponse(delResult))            {                deleteSuccessNum++;            }        }        if (deleteSuccessNum > 0)        {            return await Task.FromResult(true);        }        else        {            return await Task.FromResult(false);        }    }}

后端API接口

七天.NET 8操作SQLite入门到实战 - (2)第七天Blazor班级管理页面编写和接口对接

using Entity;using Microsoft.AspNetCore.Mvc;using Utility;namespace WebApi.Controllers{    /// <summary>    /// 学校班级管理    /// </summary>    [ApiController]    [Route("api/[controller]/[action]")]    public class SchoolClassController : ControllerBase    {        private readonly SQLiteAsyncHelper<SchoolClass> _schoolClassHelper;        /// <summary>        /// 依赖注入        /// </summary>        /// <param name="schoolClassHelper">schoolClassHelper</param>        public SchoolClassController(SQLiteAsyncHelper<SchoolClass> schoolClassHelper)        {            _schoolClassHelper = schoolClassHelper;        }        /// <summary>        /// 班级创建        /// </summary>        /// <param name="schoolClass">创建班级信息</param>        /// <returns></returns>        [HttpPost]        public async Task<ApiResponse<int>> CreateClass([FromBody] SchoolClass schoolClass)        {            try            {                var querySchoolClass = await _schoolClassHelper.QuerySingleAsync(c => c.ClassName == schoolClass.ClassName).ConfigureAwait(false);                if (querySchoolClass != null)                {                    return new ApiResponse<int>                    {                        Success = false,                        Message = $"创建班级失败,班级{schoolClass.ClassName}已存在"                    };                }                schoolClass.CreateTime = DateTime.Now;                int insertNumbers = await _schoolClassHelper.InsertAsync(schoolClass);                if (insertNumbers > 0)                {                    return new ApiResponse<int>                    {                        Success = true,                        Message = "创建班级成功"                    };                }                else                {                    return new ApiResponse<int>                    {                        Success = false,                        Message = "创建班级失败"                    };                }            }            catch (Exception ex)            {                return new ApiResponse<int>                {                    Success = false,                    Message = ex.Message                };            }        }        /// <summary>        /// 获取所有班级信息        /// </summary>        [HttpGet]        public async Task<ApiResponse<List<SchoolClass>>> GetClass()        {            try            {                var classes = await _schoolClassHelper.QueryAllAsync().ConfigureAwait(false);                return new ApiResponse<List<SchoolClass>>                {                    Success = true,                    Data = classes                };            }            catch (Exception ex)            {                return new ApiResponse<List<SchoolClass>>                {                    Success = false,                    Message = ex.Message                };            }        }        /// <summary>        /// 根据班级ID获取班级信息        /// </summary>        /// <param name="classId">班级ID</param>        /// <returns></returns>        [HttpGet("{classId}")]        public async Task<ApiResponse<SchoolClass>> GetClass(int classId)        {            try            {                var schoolClass = await _schoolClassHelper.QuerySingleAsync(c => c.ClassID == classId).ConfigureAwait(false);                if (schoolClass != null)                {                    return new ApiResponse<SchoolClass>                    {                        Success = true,                        Data = schoolClass                    };                }                else                {                    return new ApiResponse<SchoolClass>                    {                        Success = false,                        Message = "班级不存在"                    };                }            }            catch (Exception ex)            {                return new ApiResponse<SchoolClass>                {                    Success = false,                    Message = ex.Message                };            }        }        /// <summary>        /// 更新班级信息        /// </summary>        /// <param name="classId">班级ID</param>        /// <param name="updatedClass">更新的班级信息</param>        /// <returns></returns>        [HttpPut("{classId}")]        public async Task<ApiResponse<int>> UpdateClass(int classId, [FromBody] SchoolClass updatedClass)        {            try            {                var existingClass = await _schoolClassHelper.QuerySingleAsync(c => c.ClassID == classId).ConfigureAwait(false);                if (existingClass != null)                {                    existingClass.ClassName = updatedClass.ClassName;                    var updateResult = await _schoolClassHelper.UpdateAsync(existingClass).ConfigureAwait(false);                    if (updateResult > 0)                    {                        return new ApiResponse<int>                        {                            Success = true,                            Message = "班级信息更新成功"                        };                    }                    else                    {                        return new ApiResponse<int>                        {                            Success = false,                            Message = "班级信息更新失败"                        };                    }                }                else                {                    return new ApiResponse<int>                    {                        Success = false,                        Message = "班级不存在"                    };                }            }            catch (Exception ex)            {                return new ApiResponse<int>                {                    Success = false,                    Message = ex.Message                };            }        }        /// <summary>        /// 班级删除        /// </summary>        /// <param name="classId">班级ID</param>        /// <returns></returns>        [HttpDelete("{classId}")]        public async Task<ApiResponse<int>> DeleteClass(int classId)        {            try            {                var deleteResult = await _schoolClassHelper.DeleteAsync(classId).ConfigureAwait(false);                if (deleteResult > 0)                {                    return new ApiResponse<int>                    {                        Success = true,                        Message = "班级删除成功"                    };                }                else                {                    return new ApiResponse<int>                    {                        Success = true,                        Message = "班级删除失败"                    };                }            }            catch (Exception ex)            {                return new ApiResponse<int>                {                    Success = false,                    Message = ex.Message                };            }        }    }}

接口对接所遇问题及其解决方案

跨源请求 (CORS)问题

七天.NET 8操作SQLite入门到实战 - (2)第七天Blazor班级管理页面编写和接口对接

在API服务端启用跨源请求 (CORS):

调用 UseCors 扩展方法并指定 PolicyCorsName CORS 策略。UseCors 添加 CORS 中间件。对 UseCors 的调用必须放在 UseRouting 之后,但在 UseAuthorization 之前。

Program.cs添加如下代码(注意中间件顺序)

            var builder = WebApplication.CreateBuilder(args);            var PolicyCorsName = "EasySQLitePolicy";            builder.Services.AddCors(option =>            {                option.AddPolicy(PolicyCorsName, builder =>                {                    builder.AllowAnyOrigin()                      .AllowAnyMethod()                      .AllowAnyHeader();                });            });                       var app = builder.Build();                      app.UseCors(PolicyCorsName);            app.UseAuthorization();            app.MapControllers();            app.Run();            

System.Text.Json 反序列化时间异常问题

异常:

Microsoft.AspNetCore.Components.Web.ErrorBoundary[0]      System.Text.Json.JsonException: The JSON value could not be converted to System.DateTime. Path: $.Data[0].CreateTime | LineNumber: 0 | BytePositionInLine: 113.       ---> System.FormatException: The JSON value is not in a supported DateTime format.         at System.Text.Json.ThrowHelper.ThrowFormatException(DataType dataType)         at System.Text.Json.Utf8JsonReader.GetDateTime()         at System.Text.Json.Serialization.Converters.DateTimeConverter.Read(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options)

异常原因:

System.Text.Json 时间是认标准的. yyyy-MM-ddTHH:mm:ss 中间得有个T

解决方案:

注释掉服务端对时间日期类型默认格式化处理!

七天.NET 8操作SQLite入门到实战 - (2)第七天Blazor班级管理页面编写和接口对接

DotNetGuide技术社区交流群

  • DotNetGuide技术社区是一个面向.NET开发者的开源技术社区,旨在为开发者们提供全面的C#/.NET/.NET Core相关学习资料、技术分享和咨询、项目框架推荐、求职和招聘资讯、以及解决问题的平台。
  • 在DotNetGuide技术社区中,开发者们可以分享自己的技术文章、项目经验、学习心得、遇到的疑难技术问题以及解决方案,并且还有机会结识志同道合的开发者。
  • 我们致力于构建一个积极向上、和谐友善的.NET技术交流平台。无论您是初学者还是有丰富经验的开发者,我们都希望能为您提供更多的价值和成长机会。

欢迎加入DotNetGuide技术社区微信交流群?

参考文章

  • 在 ASP.NET Core 中启用跨源请求 (CORS):https://learn.microsoft.com/zh-cn/aspnet/core/security/cors?view=aspnetcore-8.0

以上就是关于七天.NET 8操作SQLite入门到实战 - (2)第七天Blazor班级管理页面编写和接口对接相关的全部内容,希望对你有帮助。欢迎持续关注程序员导航网,学习愉快哦!

暂无评论

暂无评论...