目录
1. Web Api 程序包引用
2. Web Api 的创建与Http类型的介绍
2.1 ASP.Net Core Web API项目的创建
2 .2 API接口的创建
2.3 HttpGet和HttpPost类型的区别
3.接口权限设置
4.HttpGet方法和HttpPOst方法
5.前端中用HttpGet/Poset获取接口数据
6.EF框架——配置数据库链接字符串(即将数据库中的表导入项目中)
7.Web Api和EF结合的增删改查需注意的部分代码
8. 当web返回给窗体如下特殊字符串时,在web端的program 的main函数中加入以下代码:
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
1.通过vs建立一个ASP.Net Core Web API项目;(如果没有在搜索模板中找到它,就将模板栏滑动到最后,点击蓝色字体安装多个工具和功能),然后选中如图2所示2,再安装。
生成项目后,解决方案会自动生成 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; } }
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 网址,和执行效果图 图一相对应
运行效果图
执行效果图
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? tokenObj = context.ActionArguments["token"]; //前端用到get,Post方法,用从头部获取 Taken 数据 object? tokenObj = context.HttpContext.Request.Headers["token"]; if (tokenObj == null || string.IsNullOrEmpty(tokenObj.ToString())) { context.Result = new JsonResult(WebApiResponse.Create(1, "非法登录")); } else { //登陆时返回token返回值 string token = tokenObj.ToString(); //通过token 返回对应的 人员id ,登陆的时候会返回一个Token值,将人员id和Token存储到键值对中, //此时通过GetIdByToken方法判断键值对中是否有对应的值 int userId = UserData.GetIdByToken(token); if (userId == -1) { //直接返回一个结果,修改请求的返回值,请求接口的方法不能执行,拦截之后的方法也不能执行 context.Result = new JsonResult(WebApiResponse.Create(2, "请重新登录")); return; } //查询人员信息 BaseUser user = UserData.GetDataById(userId); if (user == null) { context.Result = new JsonResult(WebApiResponse.Create(3, "用户不存在")); return; } //---------------------------------接口权限拦截----------------------------------- FilterData data = UserFilterData.GetFilteData_ByApiPath(userId, path); if (data != null) { context.Result = new JsonResult(WebApiResponse.Create(4, "用户没有权限")); return; } } } }
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; } //id public int UserId { get; set; }//人员id public string ApiPath { get; set; }//操作接口路径 public string? FilterName { get; set; }//权限名称 public string UserIdAndApiPath { get => $"{UserId}_{ApiPath}"; } }
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, DELETE request.Timeout = timeout; //请求超时时间 request.ContentType = "application/json;UTF-8"; //设置类型5 request.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请求方法 /// /// 请求路径 /// 参数 /// 主题内容 /// 请求超时时间,以毫秒位单位 ///public static 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 > Data { get; set; } //public List Data { get; set; } public T Data { get; set; } } } }
//接口地址 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中有说明,方法中对应的地址形式实际是下图中对应的地址,要仔细了解方法中是如何形成接口对应的地址的
视图 ——其他窗口——程序包管理器控制台 输入以下指令,将数据库中的表导入程序中
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();//查询所有
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();
亲测有用:
builder.Services.AddControllersWithViews().AddJsonOptions(options => { options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); });