AspNet Core Api Restful +Swagger 实现微服务之旅 (三)
(1) 访问Rest ful接口时 Token验证 返回数据格式封装
(一)访问时Token验证 返回数据格式封装
1.1访问Api接口 方法 实现
1.1.1 创建访问Restful Api帮助类
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public static string MyGet = "GET"; public static string MyPost = "POST"; public static string MyPut = "PUT"; public static string MyDELETE = "DELETE"; /// <summary> /// 访问接口信息 /// </summary> /// <param name="JsonString">抛送的字符串</param> /// <param name="achieveUrl">访问的路径</param> /// <param name="PublishKey">密钥Token</param> /// <param name="Method">访问方法</param> /// <returns></returns> public static string SendService(string JsonString, string achieveUrl, string PublishKey, string Method) { //用于返回信息的记录 var responseValue = string.Empty; if (!string.IsNullOrEmpty(achieveUrl)) { //基于http协议的请求响应 HttpWebRequest request = WebRequest.Create(achieveUrl) as HttpWebRequest; //提交方法 request.Method = Method; //设置Http标头信息 request.UserAgent = ""; //设置请求超时时间 request.Timeout = 1000 * 60 * 30; //设置读取/写入超时时间 request.ReadWriteTimeout = 1000 * 60 * 30; //request.Headers.Add("", ""); request.Headers.Add("Token", PublishKey); request.ContentType = @"application/json"; //判断访问方法 if (Method != "GET" && Method != "PUT") { request.ContentLength = Encoding.UTF8.GetByteCount(JsonString); if (!string.IsNullOrEmpty(JsonString))//如果传送的数据不为空,并且方法是put { var encoding = new UTF8Encoding(); var bytes = Encoding.GetEncoding("UTF-8").GetBytes(JsonString);// request.ContentLength = bytes.Length; using (var writeStream = request.GetRequestStream()) { writeStream.Write(bytes, 0, bytes.Length); } } } //http请求的返回状态 using (var response = (HttpWebResponse)request.GetResponse()) { //获取来自 服务器或接口的响应信息 using (var responseStream = response.GetResponseStream()) { if (responseStream != null) { using (var reader = new StreamReader(responseStream)) { responseValue = reader.ReadToEnd(); } } } } } return responseValue; }
1.1.2 Token 加密方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/// <summary> /// Base64加密 /// </summary> /// <param name="codeName">加密采用的编码方式</param> /// <param name="source">待加密的明文</param> /// <returns></returns> public static string EncodeBase64(Encoding encode, string source) { string Result = ""; byte[] bytes = encode.GetBytes(source); try { Result = Convert.ToBase64String(bytes); } catch { Result = source; } return Result; } /// <summary> /// Base64加密,采用utf8编码方式加密 /// </summary> /// <param name="source">待加密的明文</param> /// <returns>加密后的字符串</returns> public static string EncodeBase64(string source) { return EncodeBase64(Encoding.UTF8, source); }
1.1.3 获取本地IP 进行加密 用作Token
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public string GetAddressIP() { ///获取本地的IP地址 string AddressIP = string.Empty; foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList) { if (_IPAddress.AddressFamily.ToString() == "InterNetwork") { AddressIP = _IPAddress.ToString(); } } return AddressIP; }
1.1.4 读取Json文件 用作 访问接口抛送的内容
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public static string GetFileJson(string filepath) { string json = string.Empty; using (FileStream fs = new FileStream(filepath, FileMode.Open, System.IO.FileAccess.Read, FileShare.ReadWrite)) { using (StreamReader sr = new StreamReader(fs, Encoding.GetEncoding("gb2312"))) { json = sr.ReadToEnd().ToString(); } } return json; }
1.1.5 Json文件内容
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
{ "Name": "Szl", "Age": "30", "Address": "河南", "XXXXXX": "测试数据" }
1.1.6 调用接口
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// GET: Home public ActionResult Index() { string serviceURL = @"http://10.118.4.1x8:8082/szl/SzlAPI/Post"; string JsonString = GetFileJson(@"D:\VS2015Demo\RestServiceTest\UI\json.json"); string PublishKey = GetAddressIP(); ViewBag.Data = SendService(JsonString, serviceURL, EncodeBase64(PublishKey), "POST"); return View(); }
1.2 Rest Api 接口声明
1.2.1接口方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/// <summary> /// AspNet Core Post请求 /// </summary> /// <param name="value">User类</param> /// <remarks> ///访问参数 /// POST /// { /// "value": "0e7ad584-7788-4ab1-95a6-ca0a5b444cbb", /// } /// /// </remarks> /// <response code="201">返回新创建项</response> /// <response code="400">如果为空时</response> [HttpPost] [ProducesResponseType(typeof(User), 201)] [ProducesResponseType(typeof(User), 400)] public User Post([FromBody] User value) { //第二种接收值得方法 //Stream stream = HttpContext.Request.Body; //byte[] buffer = new byte[HttpContext.Request.ContentLength.Value]; //stream.Read(buffer, 0, buffer.Length); //string content = Encoding.UTF8.GetString(buffer); ////然后Json转换 User Users = new User() { UserAddress = "北京", UserAge = "身体健康无颈椎病", UserName = "Szl", XXXXXX = "注意大小写" }; return Users; }
1.2.2 User类
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class User { /// <remarks> /// 名称 /// </remarks> public string UserName { get; set; } = "名称"; /// <summary> /// 年龄 /// </summary> public string UserAge { get; set; } /// <summary> /// 地址 /// </summary> public string UserAddress { get; set; } /// <summary> /// 测试字段 /// </summary> public string XXXXXX { get; set; } }
1.3 添加 帮助类 WebApiAuthorizationFilter 对接口访问者身份Token 解密 获取访问者IP 进行验证,对返回结果进行封装
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/// <summary> /// /// </summary> public class WebApiAuthorizationFilter : IAuthorizationFilter { /// <summary> /// 调用者的身份验证 /// </summary> /// <param name="context"></param> public void OnAuthorization(AuthorizationFilterContext context) { //string IP = ((Microsoft.AspNetCore.Http.Internal.DefaultConnectionInfo)context.HttpContext.Connection).LocalIpAddress.ToString(); //获取客户端IP地址 string clientIP = ((Microsoft.AspNetCore.Http.Internal.DefaultConnectionInfo)context.HttpContext.Connection).RemoteIpAddress.ToString(); //获取Token信息 var Token = context.HttpContext.Request.Headers["Token"].FirstOrDefault(); //验证Token if (Token == "") { context.Result = new ObjectResult(new { Success = false, code = 404, msg = "请查看令牌是否包含!", data = "null" }); } else if (clientIP == DecodeBase64(Token)) { return; } else { context.Result = new ObjectResult(new { Success = false, code = 404, msg = "请查看令牌是否正确!", data = "null" }); } } /// <summary> /// Base64解密 /// </summary> /// <param name="codeName">解密采用的编码方式,注意和加密时采用的方式一致</param> /// <param name="result">待解密的密文</param> /// <returns>解密后的字符串</returns> public static string DecodeBase64(Encoding codeName, string result) { string decode = ""; byte[] bytes = Convert.FromBase64String(result); try { decode = codeName.GetString(bytes); } catch { decode = result; } return decode; } /// <summary> /// Base64解密,采用utf8编码方式解密 /// </summary> /// <param name="result">待解密的密文</param> /// <returns>解密后的字符串</returns> public static string DecodeBase64(string result) { return DecodeBase64(Encoding.UTF8, result); } }
1.4 在Startup.cs中注册服务启用 WebApiAuthorizationFilter文件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
services.AddMvc(options => { //身份验证不通过是返回结果统一化 options.Filters.Add(typeof(WebApiAuthorizationFilter)); options.RespectBrowserAcceptHeader = true; });
不加Token的结果
访问正确结果
注意 返回结果中的data的字段名 大小写的变化 前边的四位默认小写了 这是框架本身Json序列化的结果
解决方法 在Startup.cs中注册服务
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
services.AddMvc() //默认返回值 大小写不变 .AddJsonOptions(op => op.SerializerSettings.ContractResolver =new Newtonsoft.Json.Serialization.DefaultContractResolver());
今天结束 本来下面的也要说说的太晚了留着明天吧
(2) 程序错误时 返回数据格式封装
(3) 返回结果包装
(4) 访问方法时 参数必填与非必填的声明
代码中有不对的或者有更好的方法希望大家告之 相互学习 谢谢,转载注明出处
不要在自己迷茫的时候不学习