欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C# RESTful API 访问辅助类

程序员文章站 2023-11-12 08:27:34
REST 全称是 Representational State Transfer,有人说它是一种风格,并非一种标准,个人觉得挺有道理。它本身并没有创造新的技术、组件与服务,更像是告诉大家如何更好地使用现有Web标准中的一些准则和约束,也不可否认,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