1 准备工作
1.2 User
namespace Web.Domain.Users
{
///
/// 【用户--类】
///
/// 摘要:
/// 通过该实体类及其属性成员,用于实现当前程序【SecondPracticeServer】.【领域】.【用户集】.【用户】实体与“[SecondPracticeServer].[User]”表之间的CURD的交互操作,并把这些数据存储到数据库设置实例中(内存)。
///
///
public class User
{
///
/// 【编号】
///
/// 摘要:
/// 获取/设置用户实体1个指定实例的长整型编号值。
///
///
public long Id { get; set; }
///
/// 【用户名】
///
/// 摘要:
/// 获取/设置1个指定的用户名。
///
///
public string Name { get; set; }
///
/// 【密码】
///
/// 摘要:
/// 获取/设置1个指定的密码。
///
///
public string Password { get; set; }
///
/// 【已经删除?】
///
/// 摘要:
/// 获取/设置1个值false(禁用)/true(默认值,启用),该值指示用户实体1个指定实例是否已经处于启用状态。
///
///
public bool? IsEnable { get; set; }
///
/// 【创建时间】
///
/// 摘要:
/// 获取/设置用户实体1个指定实例第1次被持久化到用户表中的时间。
///
///
public DateTime CreateTime { get; set; }
}
}
1.2 EFCoreContext
using Microsoft.EntityFrameworkCore;
using Web.Domain.Users;
namespace Web.Data
{
///
/// 【EFCore上下文】
///
/// 摘要:
/// 通过该类实例化“Microsoft.EntityFrameworkCore.SqlServer”中间件,从而实例当前程中实体实例与SQLServer软件中指定数据库的数据交换操作。
///
///
public class EFCoreContext : DbContext
{
#region 拷贝构造方法
///
/// 【拷贝构造方法】
///
/// 摘要:
/// 基类构造通过该构造方法中的参数实例,连接到指定数据库(SQL Server)数据库软件中数据库。
///
///
public EFCoreContext(DbContextOptions
{
//如果(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 属性
///
/// 【用户数据库设置】
///
/// 摘要:
/// 获取/设置用户实体的数据库设置实例,用于实现当前程序【UserServer】.【领域】.【用户集】.【用户】实体与“[UserServer].[User]”表之间的CURD的交互操作,并把这些数据存储到数据库设置实例中(内存)。
///
///
public DbSet
#endregion
#region 方法--私有/保护--覆写
/// name="builder">模型生成器实例,用于把当前程序中实体和属性所定义的约束规则,映射到数据库指定表及其字段上。
///
/// 【模型生成执行...】
///
/// 摘要:
/// 该方法把当前程序中实体和属性所定义的约束规则,映射到数据库指定表及其字段上。
///
///
protected override void OnModelCreating(ModelBuilder builder)
{
//用户表约束规则,映射定义。
builder.Entity
builder.Entity
builder.Entity
builder.Entity
base.OnModelCreating(builder);
}
#endregion
}
}
2 跨域(Cors)与Swagger
2.1 appsettings.json
{
"ConnectionStrings": {
//Trusted_Connection=true或Integrated 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=SwaggerVue;Integrated Security=true;MultipleActiveResultSets=true;Trust Server Certificate=True",
"SqlServerSQL": "Data Source=.;Initial Catalog=SecondPracticeServer;Integrated Security=False;Persist Security Info=False;User ID=zz;Password=zz;MultipleActiveResultSets=true;Trust Server Certificate=True"
},
// 跨域(Cors)配置的域名及其端口集,该端口集中是否包含有vue/uni-app前端项目的访问域名及其端口,如果配置域名及其端口集中,不包含后端项目的访问域名及其端口,
//且在“Program.cs” 文件进行了限定定义,那么vue/uni-app前端是不能与.Net(Core)6后端项目进行交互操作的。
"Cors": {
"PolicyName": "CorsIpAccess", //vue/uni-app前端是不能与.Net(Core)6后端项目进行交互操作的策略名称。
"EnableAllIPs": false, //当为true时,开放所有IP均可访问。
//跨域(Cors)配置的域名及其端口集,用来限定vue/uni-app前端的访问及其交互操作。
//注意:http://127.0.0.1:1818 和 http://localhost:1818 是不一样的
"IPs": "http://localhost:8080,http://localhost:8081,http://localhost:8082,http://localhost:8083,http://localhost:8021,https://localhost:443"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
2.2 CorsMiddleware
namespace Web.Middleware
{
///
/// 【跨域访问中间件】
///
///
/// 摘要:
/// 该管道中间件类主要为了解决在由Hbuilder创建的前端Xuni-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)框架内置管道中集成当前管道中间件,解决在由Hbuilder创建的前端Xuni-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 Invoke(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
}
}
2.3 Program
using Microsoft.EntityFrameworkCore;
using Microsoft.OpenApi.Models;
using System.Reflection;
using Web.Data;
using Web.Middleware;
var builder = WebApplication.CreateBuilder(args);
//把“Microsoft.EntityFrameworkCore.SqlServer”中间件实例,依赖注入到.Net(Core)6框架内置容器中。
builder.Services.AddDbContext
//通过“DbContextOptionsBuilder”实例中的参数实例,为“Microsoft.EntityFrameworkCore.SqlServer”中间件的实例化提供参数实例,
//最终把“Microsoft.EntityFrameworkCore.SqlServer”中间件实例,依赖注入到.Net(Core)6框架内置容器中。
(options => options.UseSqlServer(builder.Configuration.GetConnectionString("SqlServerSQL")));
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
//通过AddSwaggerGen依赖注入中间方法,把Swagger中间件实例注入到.Net(Core)6框架默认容器中。
builder.Services.AddSwaggerGen(options => {
options.SwaggerDoc("v1", new OpenApiInfo { Title = "第2次实践--接口文档", Version = "v1" });
//获取"UserServer.xml"文件的文件名。
string _xmlFileName = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
//获取"SecondPracticeServer.xml"文件的绝对路径。
string _xmlFilePath = Path.Combine(AppContext.BaseDirectory, _xmlFileName);
//把控件器行为方法中的注释信息加载到"Swagger/index.html"页面中的控件器行为方法进行渲染显示。
//注意:如果不在“*.csproj”文件中启用“
options.IncludeXmlComments(_xmlFilePath, true);
});
//通过AddCors依赖注入中间方法,把Cors(跨域)中间件实例,注入到.Net(Core)6框架默认容器中。
//Cors(跨域)操作是如果“appsettings.json”文件中配置的所有域名中,至少有1个与“vue/uni-app”前台项目相匹配域名时,则“vue/uni-app”前端项目就从当前后台项目中获取相关数据,从而实现页面的渲染显示。
builder.Services.AddCors(options =>
{
//限定“appsettings.json”文件中配置的所有域名中,至少有1个与“vue/uni-app”前台项目相匹配域名,才能上“vue/uni-app”前端项目就从当前后台项目中获取相关数据,从而实现页面的渲染显示。
if (!Convert.ToBoolean(builder.Configuration["Cors:EnableAllIPs"]))
{
options.AddPolicy(builder.Configuration["Cors:PolicyName"],
policy =>
{
policy
.WithOrigins(builder.Configuration["Cors:IPs"].Split(','))
.AllowAnyHeader()
.AllowAnyMethod();
});
}
else
{
//不做限定,“vue”前台项目能够直接从当前后台项目中获取相关数据,从而实现页面的渲染显示
options.AddPolicy(builder.Configuration["Cors:PolicyName"],
policy =>
{
policy
.SetIsOriginAllowed((host) => true)
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
});
}
});
var app = builder.Build();
//把自定义管道中间中集成到.Net(Core)框架内置管道中,解决在由Hbuilder创建的前端Xuni-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
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
//把Cors(跨域)限制中间件管道中间中集成到.Net(Core)框架内置管道中,解决在由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.”。
app.UseCors(app.Configuration["Cors:PolicyName"]);
app.MapControllers();
app.Run();
3控制器实现
3.1 ResponseModel
///
///
/// 【应答模型--纪录】
///
/// 摘要:
/// 该模型纪录以泛型形式,对指定的实体所有实例及其执行状态的数据进行储存,为客户端页面的渲染提供数据支撑。
///
///
public record ResponseModel<T>
{
#region 属性
///
/// 【状态】
///
/// 摘要:
/// 获取/设置指定控制器行方法的执行结果状态码的整型值,默认值:200(执行成功状态)。
///
///
public int Status { get; set; } = 200;
///
/// 【成功?】
///
/// 摘要:
/// 获取/设置1个值false(默认值,执行失败)/true(执行成功),该值指示指定控制器行方法的执行结果状态。
///
///
public bool Success { get; set; } = false;
///
/// 【信息】
///
/// 摘要:
/// 获取/设置指定控制器行方法的执行结果信息。
///
///
public string Message { get; set; } = "";
///
/// 【应答列表】
///
/// 摘要:
/// 获取/设置列表实例,该实例用于存储指定实体中的所有实例。
///
///
public List
#endregion
}
3.2 UserController
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Web.Data;
using Web.Domain.Users;
using Web.Models;
namespace Web.Controllers
{
///
/// 用户控制器
///
[Route("[controller]/[action]")]
[ApiController]
public class UserController : Controller
{
#region 注入变量--拷贝构造方法
///
/// 【EFCore上下文实例】
///
///
/// 摘要:
/// 声明角色实体的数据库设置实例, 该实例通过EFCore数据交换中间件实现当前程序与指定数据库之间的CURD操作。
///
private readonly EFCoreContext _context;
/// name="context">模型生成器实例,用于把当前程序中实体和属性所定义的约束规则,映射到数据库指定表及其字段上。
///
/// 【拷贝构造方法】
///
///
/// 摘要:
/// 基类构造通过该构造方法中的参数实例,连接到指定数据库(SQL Server)数据库软件中数据库。
///
public UserController(EFCoreContext context)
{
_context = context;
}
#endregion
///
/// 【获取所有用户】
///
///
/// 摘要:
/// 该方法以异步方式,获取用户表中的所有用户实例,并把所有用户实例及其操作结果存储到消息模型实例中,为页面的渲染显示提供数据支撑。
///
///
/// 返回:
/// 消息模型实例,为页面的渲染显示提供数据支撑。
///
[HttpGet]
public async Task
{
List
return new ResponseModel
{
Message = "获取成功",
Success = true,
ResponseList = _userList,
};
}
///
/// 【获取所有用户--POST】
///
///
/// 摘要:
/// 该方法以异步方式,获取用户表中的所有用户实例,并把所有用户实例及其操作结果存储到消息模型实例中,为页面的渲染显示提供数据支撑。
///
///
/// 返回:
/// 消息模型实例,为页面的渲染显示提供数据支撑。
///
[HttpPost]
public async Task
{
List
return new ResponseModel
{
Message = "获取成功",
Success = true,
ResponseList = _userList,
};
}
}
}
对以上功能更为具体实现和注释见:221102_01SecondPracticeServer(模拟器、真机对后端数据的获取)。