目录
1. Web Api 程序包引用
2. Web Api 的创建与Http类型的介绍
2.1ASP.Net Core Web API项目的创建
2.2 API接口的创建
2.3HttpGet和HttpPost类型的区别
3.接口权限设置
4.HttpGet方法和HttpPOst方法
5.前端中用HttpGet/Poset获取接口数据
6.EF框架——配置数据库链接字符串(即将数据库中的表导入项目中)
7.Web Api和EF结合的增删改查需注意的部分代码
8. 当web返回给窗体如下特殊字符串时,在web端的program 的main函数中加入以下代码:
1. Web Api 程序包引用
Entity Framework (EF) Core 是轻量化、可扩展、开源和跨平台版的常用 Entity Framework 数据访问技术。
EF Core 可用作对象关系映射程序 (O/RM),这可以实现以下两点:
- 使 .NET 开发人员能够使用 .NET 对象处理数据库。
- 无需再像通常那样编写大部分数据访问代码。
准备工作:
1.创建项目:打开Visual Studio2022,选择ASP.NET Core Web应用空项目基于.Net6 创建
2.安装Nuet程序包——项目——依赖项——管理NuGet程序包(版本等级尽量一样)Microsoft.EntityFrameworkCore.SqlServer (适用于EF Core SQL Server 提供程序)
Microsoft.EntityFrameworkCore.Design(适用于EF Core .NET Core CLI 工具 )
Microsoft.EntityFrameworkCore.Tools(适用于 EF Core 的包管理器控制台工具)Microsoft.EntityFrameworkCore.Design
2. Web Api 的创建与Http类型的介绍
2.1ASP.Net Core Web API项目的创建
1.通过vs建立一个ASP.Net Core Web API项目;(如果没有在搜索模板中找到它,就将模板栏滑动到最后,点击蓝色字体安装多个工具和功能),然后选中如图2所示2,再安装。
2.2 API接口的创建
生成项目后,解决方案会自动生成 Controllers 文件夹,里面存放的就是接口;
创建:
需要注意得是:命名方法一般为 名字+后缀 Controller;(不影响接口的名字,还是前部分样式) 最大字体为接口名称
创建方式:
1.创建 API控制器
点击文件夹右键添加 控制器 选则 通用API Api控制器,之后生成如下二代码,此时的接口还是不能用的;
2.需要声明接口[ApiController] 和一级接口路径[Route(“Test”)]
(声明接口是必须的,声明接口路径最好还是带上–可以起个和接口名一样的路径好用);
3.正式定义接口和接口类型;
在这里直介绍[HttpGet(“getUsers”)]和[HttpPost(“getUsers”)]两种接口类型 格式:接口类型+方法
注意:接口类型()中填写的是二级路径(自定义),效果如上白蓝色图 蓝色GET 是类型,Test一级路径getUser就是二级路径即接口类型中的路径 ;
完整代码:
[ApiController] //声明是一个API接口[Route("Test")] //路由:api接口的路径public class TestController : Controller{///
/// 获取所有人员数据/// /// [HttpGet("getUsers")]public List GetUsers(){List list = UserManager.CreateUsers();return list;}}
2.3HttpGet和HttpPost类型的区别
1.传入参数不同
HttpGet:传入个体基本类型 如:(int,string 可传多个);
HttpPost:传入的是主题参数,当然也可以传入个体参数;
[HttpGet("getUserById")]public User GetUserById(int id){return UserManager.GetUserById(id);}//User 是一个内容[HttpPost("add")]public User Add(User user){//List users = new List();return UserManager.Add(user);}
2.HttpGet接口执行后 返回的 Request URL路径可以在通过浏览器打开,如下图:
执行的就是get 网址,和执行效果图 图一相对应
运行效果图
执行效果图
3.接口权限设置
1.创建一个类,并继承ActionFilterAttribute
2.重写方法:OnActionExecuting 和OnActionExecuted 方法
public class Intercept : ActionFilterAttribute{//在请求接口之前 public override void OnActionExecuting(ActionExecutingContext context){}//在请求接口之后 public override void OnActionExecuted(ActionExecutedContext context){ }}
3.在OnActionExecuting 方法中设置权限和Token
注:接口权限只有后半部分,通过id,和路径判断权限表中是否有对应的数据(看个人习惯,可以将存入表中数据当为赋予权限,当返回不为空就是有权限;也可以认为存入表中的数据是禁止权限,这样返回不为空,说明没有权限)
public override void OnActionExecuting(ActionExecutingContext context){Debug.Write("拦截之前");//获取请求路径string path = context.HttpContext.Request.Path;Debug.Write("请求路径:" + path);//当登录是请求路径的时候不用拦截if (path != "/baseuser/login"){//----------------------------登录Token拦截-------------------------//此时获取前端参数,没有用到前端,单纯的接口,用此方法获取token值//object" />
4.上述设置中用到的封装方法GetIdByToken(),GetFilteData_ByApiPath()
//写在登录接口中,将token和id存入UserData.AddToken(token, data.Id);//---------------------有关token的方法--------------------- ///
// 存放所有登录的Token值,键:token值,值:人员id public static readonly Dictionary Tokens = new Dictionary(); // 添加一个Taken 值public static void AddToken(string token, int id){Tokens[token] = id;}public static int GetIdByToken(string token){//通过taken寻找对应的 id 人员if (Tokens.ContainsKey(token)){return Tokens[token];}else{return -1;}}//----------------------通过获取的接口地址查询权限表,看返回结果是否为空----------- //1.缓存的权限集合存放权限,所以需要有权限数据类,即权限包含了什么public static List filterDatas = new List();/// /// 3.通过id或者接口路径来获取权限/// /// 用户id/// 接口地址/// public static FilterData GetFilteData_ByApiPath(int userid, string apipath){string str = $"{userid}_{apipath}";//数据肯定是唯一的//判断是否符合权限信息FilterData data = filterDatas.FirstOrDefault(x => x.UserIdAndApiPath == str);if (data != null){return data;}//如果没有则需要产生,且存入缓存集合WebApiContext context = null;try{context = new WebApiContext();//从数据库中查照符合的BaseRoot? baseRoot = context.BaseRoots.FirstOrDefault(x => x.UserId == userid && x.ApiPath == apipath);if (baseRoot == null){return null;}//存在就存入缓存集合中data = new FilterData();data.Id = baseRoot.Id;data.UserId = baseRoot.UserId;data.ApiPath = baseRoot.ApiPath;data.FilterName = baseRoot.RootName;filterDatas.Add(data);return data;}catch (Exception ex){Debug.WriteLine($"查询数据失败:{ex.Message}");return null;}finally{context?.Dispose();}}public class FilterData{public int Id { get; set; }//idpublic int UserId { get; set; }//人员idpublic string ApiPath { get; set; }//操作接口路径public string? FilterName { get; set; }//权限名称public string UserIdAndApiPath{get => $"{UserId}_{ApiPath}";}}
4.HttpGet方法和HttpPOst方法
public class ApiHttp{private static string Token { get; set; } = "123456";///
/// get请求方法/// /// 地址/// 参数/// 请求超时时间,以毫秒为单位/// public static string ApiGet(string path,string param,int timeout){//path:http://127.0.0.1:5000//param:id=1&name=张三//参数+路径:http://127.0.0.1:5000?id=1&name=张三string pathAndParam = path;if (!string.IsNullOrEmpty(param)){pathAndParam += "?" + param;}//创建一个HttpWebRequest对象,用来请求后台HttpWebRequest request = (HttpWebRequest)WebRequest.Create(pathAndParam);request.Method = "GET"; //请求方式:GET,POST,PUT, DELETErequest.Timeout = timeout; //请求超时时间request.ContentType = "application/json;UTF-8"; //设置类型5request.Headers.Add("token", Token); //请求头WebResponse response = request.GetResponse(); //相当于后台返回的对象Stream stream = response.GetResponseStream(); //response流StreamReader sr = new StreamReader(stream, Encoding.UTF8);string json = sr.ReadToEnd(); //读取接口返回的数据//释放对象response.Close();sr.Close();stream.Close();return json;}////// post请求方法/// /// 请求路径/// 参数/// 主题内容/// 请求超时时间,以毫秒位单位/// publicstatic string ApiPost(string path, string param, string body, int timeout = 5000){string pathAndParam = path;if (!string.IsNullOrEmpty(param)){pathAndParam += "?" + param;}//创建一个HttpWebRequest对象,用来请求后台HttpWebRequest request = (HttpWebRequest)WebRequest.Create(pathAndParam);request.Method = "POST";request.Timeout = timeout;request.ContentType = "application/json;UTF-8"; //设置类型; //设置类型request.Headers.Add("token", Token); //请求头//把主体内容添加到请求数据中if (!string.IsNullOrEmpty(body)){byte[] buffer = Encoding.UTF8.GetBytes(body);request.ContentLength = buffer.Length; //主体内容的字节长度Stream requestStream = request.GetRequestStream(); //存放请求的数据requestStream.Write(buffer, 0, buffer.Length); //把主体内容写到流中}WebResponse response = request.GetResponse();Stream responseStream = response.GetResponseStream();StreamReader sr = new StreamReader(responseStream, Encoding.UTF8);string json = sr.ReadToEnd();return json;}public class JsonData{public int Code { get; set; }public string Message { get; set; }//public List<Dictionary> Data { get; set; }//public List Data { get; set; }public T Data { get; set; }}}}
5.前端中用HttpGet/Poset获取接口数据
//接口地址string HttpPath { get; set; } = "http://127.0.0.1:5000";//和图中没有对应,需要自己注意//get string json = Http.ApiHttp.ApiGet($"{HttpPath}/TAH/TAH", null, 50000);//Post string json = ApiPost($"{HttpPath}/baseuser/updata", null, $"{body}");
注意:对应的参数在4中有说明,方法中对应的地址形式实际是下图中对应的地址,要仔细了解方法中是如何形成接口对应的地址的
6.EF框架——配置数据库链接字符串(即将数据库中的表导入项目中)
视图 ——其他窗口——程序包管理器控制台 输入以下指令,将数据库中的表导入程序中
Scaffold-DbContext -Force "Server=192.168.218.26;Database=zy04_db4;uid=zy04;Password=123456;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Context WebApiContext
- server:数据库所在的主机ip地址
- DataBase:数据库名称
- uid:用户名
- PassWorf:密码
- Models:存放自动创建的实体类的文件夹(可以自己命名)
- WebApiContext:直接操作数据库的类名(可以自己命名)
- 有了WebApiContext类之后,不用再写连接数据库的逻辑了,只需要实例对应的数据表就可以操作如:
WebApiContext con=new WebAiContext();List list=con.BaseUsers.ToList();//查询所有
7.Web Api和EF结合的增删改查需注意的部分代码
1.通过***查找:FirstOrDefault
WebApiContext context = null;context = new WebApiContext();BaseUser user = context.BaseUsers.FirstOrDefault(x => x.Id == id);
2.增删改之后,需要保存
context.BaseRoles.Update(role);context.BaseRoles.Add(role);context.BaseRoles.Remove(role);context.SaveChanges();
8. 当web返回给窗体如下特殊字符串时,在web端的program 的main函数中加入以下代码:
亲测有用:
builder.Services.AddControllersWithViews().AddJsonOptions(options =>{options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);});