当前位置:首页 » ASP.NET技术教程

AspNet Core Api Restful +Swagger 实现微服务之旅 (三)

2017-12-21 00:20 本站整理 浏览(7)

(1)  访问Rest ful接口时 Token验证  返回数据格式封装

(一)访问时Token验证  返回数据格式封装

1.1访问Api接口 方法 实现

        1.1.1 创建访问Restful Api帮助类

 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;
        }
View Code

1.1.2  Token 加密方法

/// <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);
        }
View Code

   1.1.3 获取本地IP 进行加密 用作Token

   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;
        }
View Code

   1.1.4  读取Json文件 用作 访问接口抛送的内容

     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;
        }
View Code

1.1.5 Json文件内容

    {
        "Name": "Szl",
        "Age": "30",
      "Address": "河南",
      "XXXXXX": "测试数据"
    }
View Code

      1.1.6 调用接口

 // 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();
        }
View Code

  1.2 Rest Api 接口声明

       1.2.1接口方法

/// <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;
        }
View Code

       1.2.2 User类

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; }

    }
View Code

  1.3 添加 帮助类 WebApiAuthorizationFilter 对接口访问者身份Token 解密 获取访问者IP 进行验证,对返回结果进行封装

    /// <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);
        }
    }
View Code

   1.4 在Startup.cs中注册服务启用 WebApiAuthorizationFilter文件

           services.AddMvc(options =>
            {
                //身份验证不通过是返回结果统一化
                options.Filters.Add(typeof(WebApiAuthorizationFilter));
                options.RespectBrowserAcceptHeader = true;
            });
View Code

不加Token的结果

访问正确结果

注意 返回结果中的data的字段名 大小写的变化  前边的四位默认小写了 这是框架本身Json序列化的结果

解决方法  在Startup.cs中注册服务

services.AddMvc()
            //默认返回值 大小写不变
           .AddJsonOptions(op => op.SerializerSettings.ContractResolver =new Newtonsoft.Json.Serialization.DefaultContractResolver()); 
View Code

今天结束 本来下面的也要说说的太晚了留着明天吧

(2)  程序错误时  返回数据格式封装

(3)  返回结果包装

(4)  访问方法时 参数必填与非必填的声明

    代码中有不对的或者有更好的方法希望大家告之 相互学习 谢谢,转载注明出处