在C#中使用RESTful API的幾種好方法


什么是Restful API

  • REST

    即Representational State Transfer的縮寫。直接翻譯的意思是"表現層狀態轉化"。
    它是一種互聯網應用程序的API設計理念:URL定位資源,用HTTP動詞描述操作。

  • URI

    即統一資源標識符,服務器上每一種資源,比如文檔、圖像、視頻片段、程序 都由一個通用資源標識符(Uniform Resource Identifier, 簡稱"URI")進行定位。

  • HTTP動詞

    • GET(SELECT):從服務器取出資源(一項或多項)。
    • POST(CREATE):在服務器新建一個資源。
    • PUT(UPDATE):在服務器更新資源(客戶端提供改變后的完整資源)。
    • PATCH(UPDATE):在服務器更新資源(客戶端提供改變的屬性)。
    • DELETE(DELETE):從服務器刪除資源。

通過Web開發的路徑,您發現自己遲早需要處理外部API(應用程序編程接口)。在本文中,我的目標是列出在C#項目中使用RESTful API的方法的最全面列表,並通過一些簡單示例向您展示如何做到這一點。閱讀本文之后,您將更深入地了解哪些選項可用,以及下次需要使用RESTful API時如何選擇正確的選項.

如何使用RESTful API

有幾種方法可以在C#中使用RESTful API:

例如,我們將通過GitHub API收集有關RestSharp發布版本及其發布日期的信息。此信息是公開可用的,您可以在此處查看原始JSON響應的內容:查看RestSharp版本信息

HttpWebRequest / Response類

這是WebRequest 類的特定於HTTP的實現,該實現最初用於處理HTTP請求,但已過時並由WebClient該類代替。
該HttpWebRequest 班提供細粒度控制的要求制定過程的每一個環節。您可以想象,這可能是一把雙刃劍,您很容易浪費大量時間來微調您的請求。另一方面,這可能正是您針對特定案例所需要的。
HttpWebRequest 類不會阻止用戶界面,也就是說,我相信您會同意這一點,這一點非常重要。
HttpWebResponse 類為傳入的響應提供了一個容器。
這是有關如何使用這些類使用API​​的簡單示例:

public class HttpWebRequestHandler : IRequestHandler
{
    public string GetReleases(string url)
    {
        var request = (HttpWebRequest)WebRequest.Create(url);
 
        request.Method = "GET";
        request.UserAgent = RequestConstants.UserAgentValue;
        request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
 
        var content = string.Empty;
 
        using (var response = (HttpWebResponse)request.GetResponse())
        {
            using (var stream = response.GetResponseStream())
            {
                using (var sr = new StreamReader(stream))
                {
                    content = sr.ReadToEnd();
                }
            }
        }
 
        return content;
    }
}

盡管是一個簡單的示例,但是當您需要處理更復雜的需求(例如,發布表單信息,授權等)時,它會變得更加復雜。

WebClient類

這個類是包裝器HttpWebRequest。它通過HttpWebRequest從開發人員中提取的細節來簡化流程。該代碼更容易編寫,並且您通過這種方式犯錯誤的可能性較小。如果您想編寫更少的代碼,而不用擔心所有細節,並且執行速度是不重要的,請考慮使用WebClientclass。

這個例子應該給你一個大概的想法WebClient,與HttpWebRequest/ HttpWebResponse方法相比,使用起來要容易得多:

public string GetReleases(string url)
{
    var client = new WebClient();
    client.Headers.Add(RequestConstants.UserAgent, RequestConstants.UserAgentValue);
 
    var response = client.DownloadString(url);
 
    return response;
}

除了其他DownloadString方法,WebClient類還提供了許多其他有用的方法。我們可以輕松地使用它來操作字符串,文件或字節數組,代價是性能比HttpWebRequest/ HttpWebResponse方法要慢幾毫秒。
無論是HttpWebRequest/ HttpWebResponse和WebClient類在舊版本的.NET可供選擇。 WebClient MSDN

HttpClient類

HttpClient 是“new kid on the block”,它提供了舊庫所缺乏的一些現代.NET功能。例如,您可以使用的單個實例發送多個請求HttpClient,它不綁定到特定的HTTP服務器或主機,而是使用了異步/等待機制。

您可以在此視頻中找到使用HttpClient的五個很好的理由:

  1. 強類型標題。
  2. 共享緩存,cookie和憑據
  3. 訪問cookie和共享cookie
  4. 控制緩存和共享緩存。
  5. 將您的代碼模塊注入ASP.NET管道。清潔和模塊化的代碼。
    HttpClient在我們的示例中,如下:
public string GetReleases(string url)
{
    using (var httpClient = new HttpClient())
    {
        httpClient.DefaultRequestHeaders.Add(RequestConstants.UserAgent, RequestConstants.UserAgentValue);
 
        var response = httpClient.GetStringAsync(new Uri(url)).Result;
 
        return response;
    }
}

另外,我還要提到一件事。是否HttpClient應該包裝在using塊中還是在應用程序級別上進行靜態討論。盡管它實現了IDisposable,但似乎通過將它包裝在using塊中,會使應用程序出現故障並獲得SocketException。靜態初始化與動態使用測試
並且不要忘記,由於是現代的,它HttpClient是.NET 4.5專有的,因此在某些舊項目中使用它可能會遇到麻煩。

RestSharp

RestSharp是標准.NET庫的OpenSource替代品,也是目前最酷的.NET庫之一。它以NuGet軟件包的形式提供,出於某些原因,您應該考慮嘗試一下。

就像HttpClientRestSharp 一樣,它是一個現代而全面的庫,易於使用且令人愉悅,同時仍支持舊版本的.NET Framework。它具有內置的身份驗證和序列化/反序列化機制,但允許您使用自定義機制覆蓋它們。它可跨平台使用,並支持OAuth1,OAuth2,基本,NTLM和基於參數的身份驗證。您可以選擇同步或異步工作。該庫還有很多其他功能,而這些只是它提供的眾多好處中的一部分。有關RestSharp的用法和功能的詳細信息,您可以訪問GitHub上的RestSharp 頁面。

現在,讓我們嘗試使用RestSharp get獲取RestSharp版本的列表:

public string GetReleases(string url)
{
    var client = new RestClient(url);
 
    var response = client.Execute(new RestRequest());
 
    return response.Content;
}

很簡單。但是請不要讓自己愚弄,RestSharp非常靈活,擁有使用RESTful API時幾乎實現任何目的所需的所有工具。

在此示例中要注意的一件事是,由於示例的一致性,我沒有使用RestSharp的反序列化機制,這有點浪費,但是我鼓勵您使用它,因為它確實非常容易和方便。因此,您可以輕松地制作一個這樣的Model:

public class GitHubRelease
{
    [JsonProperty(PropertyName = "name")]
    public string Name { get; set; }
    [JsonProperty(PropertyName = "published_at")]
    public string PublishedAt { get; set; }
}

然后使用該Execute方法直接反序列化對該容器的響應。您可以僅添加所需的屬性,並使用屬性JsonProperty將它們映射到C#屬性(很好的觸摸)。由於我們在響應中獲得了發布列表,因此我們將List 用作包含類型。

public List<GitHubRelease> GetDeserializedReleases(string url)
{
    var client = new RestClient(url);
 
    var response = client.Execute<List<GitHubRelease>>(new RestRequest());
 
    return response.Data;
}

非常簡單而優雅的方式來獲取我們的數據。

RestSharp不僅具有發送GET請求的功能,還可以自己探索並觀察它的酷炫之處。

RestSharp案例中要補充的最后一點是,它的存儲庫需要維護者。

Flurl

Flurl代表Fluent Url Builder,這是庫構建其查詢的方式。對於不熟悉流利的做事方式的人來說,流利只是意味着庫的構建方式是將方法鏈接在一起以實現更高的可讀性,類似於人類語言。
為了使事情更容易理解,讓我們舉一些例子(這個例子來自官方文檔):

// Flurl will use 1 HttpClient instance per host
var person = await "https://api.com"
    .AppendPathSegment("person")
    .SetQueryParams(new { a = 1, b = 2 })
    .WithOAuthBearerToken("my_oauth_token")
    .PostJsonAsync(new
    {
        first_name = "Claire",
        last_name = "Underwood"
    })
    .ReceiveJson<Person>();

您可以看到方法如何鏈接在一起以完成“句子”。

在后台,Flurl使用HttpClient或通過自己的語法糖增強HttpClient庫。因此,這意味着Flurl是一個異步庫,因此請牢記這一點。

與其他高級庫一樣,我們可以通過兩種不同的方式來做到這一點:

public string GetReleases(string url)
{
    var result = url
        .WithHeader(RequestConstants.UserAgent, RequestConstants.UserAgentValue)
        .GetJsonAsync<List<GitHubRelease>>()
        .Result;
 
    return JsonConvert.SerializeObject(result);
}

這種方式相當糟糕,因為我們只序列化結果以便稍后對其進行反序列化。如果您使用的是Flurl之類的庫,則不應以這種方式進行操作。

更好的做事方式是:

public List<GitHubRelease> GetDeserializedReleases(string url)
{
    var result = url
        .WithHeader(RequestConstants.UserAgent, RequestConstants.UserAgentValue)
        .GetJsonAsync<List<GitHubRelease>>()
        .Result;
 
    return result;
}

使用.Result,我們將強制代碼的同步行為。使用Flurl的實際和預期方式如下所示:

public async Task<List<GitHubRelease>> GetDeserializedReleases(string url)
{
    var result = await url
        .WithHeader(RequestConstants.UserAgent, RequestConstants.UserAgentValue)
        .GetJsonAsync<List<GitHubRelease>>();
 
    return result;
}

這里對Flurl做了簡單的展示,易於使用,現代,可讀性和可測試性。

更多請查看原文


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM