• C# RESTful API


    C# RESTful API 

    REST 全称是 Representational State Transfer,有人说它是一种风格,并非一种标准,个人觉得挺有道理。它本身并没有创造新的技术、组件与服务,更像是告诉大家如何更好地使用现有Web标准中的一些准则和约束,也不可否认,RESTFul 是目前最流行的 API 设计规范,用于 Web 数据接口的设计。

     

    RESTful 风格的 API,在 HTTP 协议上使用的是标准 HTTP 方法,GET、PUT、POST 和 DELETE 等。

     

    常用实践

     

    (1)API 返回结果通常为 JSON 形式,请求的头部属性 Accept 通常设置为 application/json

     

    (2)请求的 Body 数据部分使用 JSON 形式

     

    (3)鉴权信息使用 JWT 等形式的授权码方式,放在请求头部属性中传输,属性名称自定义,如 auth,token 等等

     

    辅助类设计

     

    (1)属性定义

     

    定义属性:TokenHeaderName

     

    上述实践描述中,自定义部分为鉴权信息在头部属性中的名称,定义该属性表示这个名称。

     

    定义属性:DefaultToken

     

    考虑到鉴权信息在某些场景下可初始为一个固定值,定义该属性在默认情况下使用。

     

    具体定义如下:

     

    // 鉴权 token 的请求头属性名称
    public String TokenHeaderName { get; set; }
    
    // 默认的鉴权 token 信息
    public String DefaultToken { get; set; }

     

    (2)方法定义

     

    方法定义跟标准的 HTTP 方法一致,这里定义常用的 Get、Put、Post、Delete 方法。

     

    再抽取其中会重复的部分形成一些私有方法来复用,再重载一些方法使得可以应用默认参数值。

     

    (2.1)构造方法

     

    构造时可以指定鉴权头部属性名和 token,也可以不指定。

     

    public RestApiVisitHelper()
    {
    
    }
    
    // 构造时设置鉴权 token 的请求头属性名称
    public RestApiVisitHelper(String tokenHeaderName)
    {
        TokenHeaderName = tokenHeaderName;
    }
    
    // 构造时设置鉴权 token 的请求头属性名称,以及默认的 token 值
    public RestApiVisitHelper(String tokenHeaderName, String defaultToken){
        TokenHeaderName = tokenHeaderName;
        DefaultToken = defaultToken;
    }  

     

    (2.2)访问所需辅助方法

     

    (2.2.1) 创建 WebClient,设置好相关属性,包括鉴权头部信息

     

    // 创建 WebClient 并设置好 token 信息
    private WebClient CreateWebClient(String token)
    {
        System.Net.ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true);
        System.Net.WebClient webClientObj = new System.Net.WebClient();
        webClientObj.Headers.Add("Accept", "application/json");
        if (!String.IsNullOrEmpty(TokenHeaderName) && !String.IsNullOrEmpty(token))
        {
            webClientObj.Headers.Add(TokenHeaderName, token);
        }
        webClientObj.Encoding = Encoding.UTF8;
        return webClientObj;
    }

     

    (2.2.2)将查询参数格式化拼接成最终 url

     

    // 将查询参数格式化拼接到 url 上形成最终的访问地址
    private String FormatUrl(String apiUrl, Hashtable queryParams)
    {
        String queryString = "";
        foreach (var k in queryParams.Keys)
        {
            if (!String.IsNullOrEmpty(queryString))
            {
                queryString += "&";
            }
            queryString += String.Format("{0}={1}", k, queryParams[k]);
        }
        if (!String.IsNullOrEmpty(queryString))
        {
            apiUrl += "?" + queryString;
        }
        return apiUrl;
    }

     

    (2.2.3)异常统一处理

     

    出现请求异常时,可以统一进行处理,具体返回结果可自行定义。

     

    // 异常时返回的信息:应该根据实际需要进行返回
    private String WhenError(Exception e)
    {
        JObject result = new JObject();
        result["err_code"] = -1;  
        if (e is WebException)
        {
            var we = (WebException)e;
            if (we.Response != null)  // 如果有输出则仍然返回实际输出
            {
                return new StreamReader(we.Response.GetResponseStream()).ReadToEnd();
            }
            else
            {                    
                result["err_msg"] = we.Message;
            }
        }
        else
        { 
            result["err_msg"] = e.Message; 
        }
        return result.ToString(Newtonsoft.Json.Formatting.None);
    }

     

    (2.3)公开方法具体实现

     

    有了以上辅助方法,实现代码会变得简洁,且各个方法代码结构类似。以下以 Post 方法(包括重载) 为例展示基本实现。

     

    /// <summary>
    /// Post Api 返回结果文本,使用默认的鉴权 token
    /// </summary>
    /// <param name="apiUrl"></param>
    /// <param name="queryParams"></param>
    /// <param name="body"></param>
    /// <returns></returns>
    public String Post(string apiUrl, Hashtable queryParams, JObject body)
    {
        return Post(apiUrl, queryParams, body, DefaultToken);
    }
    
    /// <summary>
    /// Post Api 返回结果文本
    /// </summary>
    /// <param name="apiUrl"></param>
    /// <param name="queryParams"></param>
    /// <param name="body"></param>
    /// <param name="token"></param>
    /// <returns></returns>
    public String Post(string apiUrl, Hashtable queryParams, JObject body, String token)
    {
        System.Net.WebClient webClientObj = CreateWebClient(token);
    
        apiUrl = FormatUrl(apiUrl, queryParams);
        try
        {
            String result = webClientObj.UploadString(apiUrl, "POST", body.ToString(Newtonsoft.Json.Formatting.None));
            return result;
        }
        catch (Exception ce)
        {
            return WhenError(ce);
        }
    }

     

    完整源码

     

    https://github.com/triplestudio/helloworld/blob/master/RestApiVisitHelper.cs

  • 相关阅读:
    SET NOCOUNT ON 作用
    C# WinForm控件之Dock先后顺序调整
    Sql查询按某字段值排序
    sql server 中DateName()函数及DatePart()函数
    js的字符串代码库及讲解
    js实现字符串格式的日期加一天
    1、用datetimepicker插件实现限定时间范围的选择 2、时间插件实现默认当天的时间和只能选择小于今天的日期
    js判断开始时间不能小于结束时间
    vue监听路由的变化,跳转到同一个页面时,Url改变但视图未重新加载问题
    js对json格式对象进行增加,修改,删除
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/11144630.html
Copyright © 2020-2023  润新知