一文詳解如何在C#中使用RESTful API
通過Web開發(fā)的路徑,您發(fā)現(xiàn)自己遲早需要處理外部API(應(yīng)用程序編程接口)。在本文中,我的目標是列出在C#項目中使用RESTful API的方法的最全面列表,并通過一些簡單示例向您展示如何做到這一點。
閱讀該文章后,您將更深入地了解可以使用哪些選項,以及下次需要使用RESTful API時如何選擇正確的選項。
什么是RESTful API?
因此,在開始之前,您可能想知道API代表什么,以及RESTful的全部含義是什么?
簡而言之,API是軟件應(yīng)用程序之間的層。您可以將請求發(fā)送到API,并從中獲得響應(yīng)。API隱藏了軟件應(yīng)用程序具體實現(xiàn)的所有細節(jié),并公開了您用于與該應(yīng)用程序通信的接口。
整個互聯(lián)網(wǎng)是由API組成的大型蜘蛛網(wǎng)。我們使用API在應(yīng)用程序之間通信和關(guān)聯(lián)信息。我們有一個API,可以處理幾乎所有內(nèi)容。您每天使用的大多數(shù)服務(wù)都有自己的API(GoogleMaps,F(xiàn)acebook,Twitter,Instagram,天氣門戶…)
RESTful部分意味著API是根據(jù)REST(表示狀態(tài)傳輸)的原理和規(guī)則來實現(xiàn)的,REST是網(wǎng)絡(luò)的基礎(chǔ)架構(gòu)原理。RESTful API在大多數(shù)情況下會返回純文本,JSON或XML響應(yīng)。更詳細地解釋REST不在本文的討論范圍之內(nèi),但是您可以在我們的文章REST API最佳實踐中[6]閱讀有關(guān)REST的更多信息。
如何使用RESTful API
好吧,讓我們進入整個故事中最重要的部分。
有幾種方法可以在C#中使用RESTful API:
•HttpWebRequest/Response Class
•WebClient Class
•HttpClient Class
•RestSharp NuGet Package
•ServiceStack Http Utils
•Flurl
•DalSoft
.RestClient
這些中的每一個都有優(yōu)點和缺點,因此讓我們仔細研究它們,看看它們提供了什么。
例如,我們將通過GitHub API收集有關(guān)RestSharp回購版本及其發(fā)布日期的信息。此信息是公開可用的,您可以在此處查看原始JSON響應(yīng)的外觀: RestSharp版本
我們將利用Json.NET庫的幫助來反序列化獲得的響應(yīng)。同樣,對于某些示例,我們將使用庫的內(nèi)置反序列化機制。選擇哪種方式取決于您,因為沒有正確的方法。(您可以在源代碼中看到這兩種機制的實現(xiàn))。
我期望通過接下來的幾個示例得到一個反序列化JArray(為簡單起見),其中包含RestSharp發(fā)布信息。之后,我們可以遍歷它以獲得以下結(jié)果。
HttpWebRequest / Response類
這是WebRequest 類的特定于HTTP的實現(xiàn),該實現(xiàn)最初用于處理HTTP請求,但已過時并由WebClient該類代替 。
該HttpWebRequest 提供細粒度控制的要求制定過程的每一個環(huán)節(jié)。您可以想象,這可能是一把雙刃劍,您很容易浪費大量時間來微調(diào)您的請求。另一方面,這可能正是您針對特定案例所需要的。
HttpWebRequest 類不會阻止用戶界面,也就是說,我相信您會同意這一點,這一點非常重要。
HttpWebResponse 類為傳入的響應(yīng)提供了一個容器。
這是有關(guān)如何使用這些類使用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;
}
}
盡管是一個簡單的示例,但是當您需要處理更復(fù)雜的方案(例如,發(fā)布表單信息,授權(quán)等)時,它會變得更加復(fù)雜。
WebClient類別
這個類對HttpWebRequest的包裝。它通過HttpWebRequest從開發(fā)人員中提取的細節(jié)來簡化流程。該代碼更容易編寫,并且您通過這種方式犯錯誤的可能性較小。如果您想編寫更少的代碼,而不用擔心所有細節(jié),并且執(zhí)行速度是不重要的,請考慮使用WebClientclass。
這個示例應(yīng)該使您大致了解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類還提供了許多其他有用的方法,使我們的生活更輕松。我們可以輕松地使用它來操作字符串,文件或字節(jié)數(shù)組,并且價格比HttpWebRequest/ HttpWebResponse方法要慢幾毫秒。
無論是HttpWebRequest/ HttpWebResponse和WebClient類在舊版本的.NET可供選擇。如果您對其他產(chǎn)品感興趣,請務(wù)必查看MSDN[16]WebClient。
HttpClient類
HttpClient 是“新人”,它提供了舊庫所缺乏的一些現(xiàn)代.NET功能。例如,您可以使用的單個實例發(fā)送多個請求HttpClient,它不綁定到特定的HTTP服務(wù)器或主機,而是使用async / await機制。
您可以在此視頻中找到使用HttpClient的五個很好的理由:
•強類型標題。
•共享緩存,cookie和憑據(jù)
•訪問cookie和共享cookie
•控制緩存和共享緩存。
•將您的代碼模塊注入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;
}
}
為了簡單起見,我同步實現(xiàn)了它。每個HttpClient方法都應(yīng)異步使用,應(yīng)該以這種方式使用。
另外,我還要提到一件事。是否HttpClient應(yīng)該包裝在using塊中還是在應(yīng)用程序級別上進行靜態(tài)討論。盡管它實現(xiàn)了IDisposable,但似乎通過將它包裝在using塊中,會使應(yīng)用程序出現(xiàn)故障并獲得SocketException。而在ANKIT博客中,提供了基于很多有利于靜態(tài)初始化的HttpClient性能測試結(jié)果是。請務(wù)必閱讀這些博客文章,因為它們可以幫助您更了解該HttpClient 庫的正確用法。
并且不要忘記,由于是新的,HttpClient是.NET 4.5以上版本才有,因此在某些舊項目中使用它可能會遇到麻煩。
RestSharp
RestSharp是標準.NET庫的OpenSource替代品,也是目前最酷的.NET庫之一。它以NuGet軟件包的形式提供,出于某些原因,您應(yīng)該考慮嘗試一下。
就像HttpClientRestSharp 一樣,它是一個現(xiàn)代而全面的庫,易于使用且令人愉悅,同時仍支持舊版本的.NET Framework。它具有內(nèi)置的身份驗證和序列化/反序列化機制,但允許您使用自定義機制[24]覆蓋它們。它可跨平臺使用,并支持OAuth1,OAuth2,基本,NTLM和基于參數(shù)的身份驗證。您可以選擇同步或異步工作。該庫還有很多其他功能,而這些只是它提供的眾多好處中的一部分。有關(guān)RestSharp的用法和功能的詳細信息,您可以訪問GitHub上的RestSharp 頁面。
現(xiàn)在,讓我們嘗試使用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時幾乎可以實現(xiàn)所有功能所需的所有工具。
在此示例中要注意的一件事是,由于示例的一致性,我沒有使用RestSharp的反序列化機制,這有點浪費,但是我鼓勵您使用它,因為它確實非常容易和方便。因此,您可以輕松地制作一個這樣的容器:
public class GitHubRelease
{
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "published_at")]
public string PublishedAt { get; set; }
}
然后使用該Execute方法直接反序列化對該容器的響應(yīng)。您可以僅添加所需的屬性,并使用屬性JsonProperty將它們映射到C#屬性(很好的觸摸)。由于我們在響應(yīng)中獲得了發(fā)布列表,因此我們將List 用作包含類型。
public List<GitHubRelease> GetDeserializedReleases(string url)
{
var client = new RestClient(url);
var response = client.Execute<List<GitHubRelease>>(new RestRequest());
return response.Data;
}
一種非常直接而優(yōu)雅的方式來獲取我們的數(shù)據(jù)。
RestSharp不僅具有發(fā)送GET請求的功能,還可以自己探索并觀察它的酷炫之處。
在RestSharp案例中要補充的最后一點是,其存儲庫需要維護者。如果您想了解更多有關(guān)這個很棒的庫的信息,我敦促您前往RestSharp存儲庫,幫助該項目繼續(xù)發(fā)展并變得更好。
ServiceStack Http實用程序
另一個庫,但與RestSharp不同,ServiceStack似乎得到了適當維護,并與現(xiàn)代API[29]趨勢保持同步。ServiceStack功能列表令人印象深刻,并且肯定具有各種應(yīng)用程序。
在這里對我們最有用的是演示如何使用外部RESTful API。ServiceStack具有一種專門的方式來處理稱為Http Utils的[30]第三方HTTP API 。
讓我們看看如何首先使用Json.NET解析器來獲取RestSharp版本是如何使用ServiceStack Http Utils。
public string GetReleases(string url)
{
var response = url.GetJsonFromUrl(webReq =>
{
webReq.UserAgent = RequestConstants.UserAgentValue;
});
return response;
}
您還可以選擇將其留給ServiceStack解析器。我們可以重用本文前面定義的Release類 。
public List<GitHubRelease> GetDeserializedReleases(string url)
{
var releases = url.GetJsonFromUrl(webReq =>
{
webReq.UserAgent = RequestConstants.UserAgentValue;
}).FromJson<List<GitHubRelease>>();
return releases;
}
如您所見,無論哪種方式都可以正常工作,并且您可以選擇是獲取字符串響應(yīng)還是立即反序列化它。
盡管ServiceStack是我們偶然發(fā)現(xiàn)的最后一個庫,但令我感到驚訝的是,它使用起來如此容易,而且我認為它將來可能成為我處理API和服務(wù)的首選工具。
Flurl
評論庫中許多人要求的圖書館之一,并在Internet上受到許多人的喜愛,但仍吸引著人們。
Flurl代表Fluent Url Builder,這是庫構(gòu)建其查詢的方式。對于不熟悉flurl的做事方式的人來說,flurl只是意味著庫的構(gòu)建方式是將方法鏈接在一起以實現(xiàn)更高的可讀性,類似于人類語言。
為了使事情更容易理解,讓我們舉一些例子(這個例子來自官方文檔):
// 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>();
您可以看到方法如何鏈接在一起以完成“句子”。
在后臺,F(xiàn)lurl使用HttpClient或通過自己的語法糖增強HttpClient庫。因此,這意味著Flurl是一個異步庫,因此請牢記這一點。
與其他高級庫一樣,我們可以通過兩種不同的方式來做到這一點:
public string GetReleases(string url)
{
var result = url
.WithHeader(RequestConstants.UserAgent, RequestConstants.UserAgentValue)
.GetJsonAsync<List<GitHubRelease>>()
.Result;
return JsonConvert.SerializeObject(result);
}
這種方式相當糟糕,因為我們只是序列化結(jié)果,以便稍后對其進行反序列化。如果您使用的是Flurl之類的庫,則不應(yīng)以這種方式進行操作。
更好的做事方式是:
public List<GitHubRelease> GetDeserializedReleases(string url)
{
var result = url
.WithHeader(RequestConstants.UserAgent, RequestConstants.UserAgentValue)
.GetJsonAsync<List<GitHubRelease>>()
.Result;
return result;
}
隨著.Result我們強迫代碼的同步行為。使用Flurl的實際和預(yù)期方式如下所示:
public async Task<List<GitHubRelease>> GetDeserializedReleases(string url)
{
var result = await url
.WithHeader(RequestConstants.UserAgent, RequestConstants.UserAgentValue)
.GetJsonAsync<List<GitHubRelease>>();
return result;
}
這展示了Flurl庫的全部潛力。
DalSoft.RestClient
現(xiàn)在,此列表與該列表中的任何內(nèi)容都有些不同。但這一點有所不同。
讓我們看看如何使用DalSoft.RestClient來使用GitHub API,然后談?wù)撐覀円淹瓿傻墓ぷ鳌?/p>
首先,您可以通過輸入以下內(nèi)容,通過NuGet軟件包管理器下載DalSoft.RestClient: Install-Package DalSoft.RestClient
或通過.NET Core CLI: dotnet add package DalSoft.RestClient
兩種方法都可以。
擁有圖書館后,我們可以執(zhí)行以下操作:
public string GetReleases(string url)
{
dynamic client = new RestClient(RequestConstants.BaseUrl,
new Headers { { RequestConstants.UserAgent, RequestConstants.UserAgentValue } });
var response = client.repos.restsharp.restsharp.releases.Get().Result.ToString();
return response;
}
或最好使用DalSoft.RestClient在充分利用其功能的同時立即反序列化響應(yīng):
public async Task<List<GitHubRelease>> GetDeserializedReleases(string url)
{
dynamic client = new RestClient(RequestConstants.BaseUrl,
new Headers { { RequestConstants.UserAgent, RequestConstants.UserAgentValue } });
var response = await client.repos.restsharp.restsharp.releases.Get();
return response;
}
因此,讓我們稍微討論一下這些例子。
乍一看,它似乎并不比我們使用的其他一些現(xiàn)代庫簡單得多。
但這歸結(jié)為形成請求的方式,那就是利用RestClient的動態(tài)特性。例如,我們的BaseUrl是https://api.github.com ,我們需要進入https://api.github.com/repos/restsharp/restsharp/releases。我們可以通過動態(tài)創(chuàng)建客戶端,然后通過鏈接Url的“部分”來形成Url來做到這一點:
await client.repos.restsharp.restsharp.releases.Get();
形成請求的一種非常獨特的方法。還有一個非常靈活的!
因此,一旦我們設(shè)置了基本的網(wǎng)址,就可以輕松地使用不同的端點。
還值得一提的是,我們得到的JSON響應(yīng)會自動進行類型轉(zhuǎn)換。如您在第二個示例中看到的那樣,我們方法的返回值是Task>. So,該庫足夠聰明,可以將響應(yīng)轉(zhuǎn)換為我們的類型(依賴于Json.NET)。這使我們的生活更加輕松。
除了易于理解和使用之外,DalSoft.RestClient還具有現(xiàn)代庫應(yīng)具備的所有功能。它是可配置的,異步的,可擴展的,可測試的,并且支持多個平臺。
其他選擇
對于您的特定問題,還有許多其他選項可用。您可以使用任何這些庫來使用特定的RESTful API。例如,octokit.net專門用于GitHub API,F(xiàn)acebook SDK用于使用Facebook API,并且還有許多其他功能可用于任何用途。
雖然這些庫是專門為這些API而設(shè)計的,并且可能擅長于它們的用途,但它們的用途是有限的,因為您經(jīng)常需要在應(yīng)用程序中連接多個API。這可能會導致每個實現(xiàn)都有不同的實現(xiàn)方式,以及更多的依賴關(guān)系,這可能導致重復(fù)并且容易出錯。庫越具體,其靈活性就越差。
結(jié)論
因此,總而言之,我們已經(jīng)討論了可用于使用RESTful API的不同工具。我們已經(jīng)提到了一些.NET庫,可以這樣做HttpWebRequest,WebClient和HttpClient,以及一些驚人的第三方工具,如RestSharp和ServiceStack。您還對這些工具進行了簡短的介紹,并給出了一些非常簡單的示例來向您展示如何開始使用它們。
我認為您現(xiàn)在至少有95%準備使用一些REST。繼續(xù)展開翅膀,探索并找到更多有趣且有趣的方式來使用和連接不同的API。
到此這篇關(guān)于一文詳解如何在C#中使用RESTful API的文章就介紹到這了,更多相關(guān)C#使用RESTful API內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#訪問C++動態(tài)分配的數(shù)組指針(實例講解)
下面小編就為大家分享一篇C#訪問C++動態(tài)分配的數(shù)組指針(實例講解),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2017-12-12
VS?Code里使用Debugger?for?Unity插件調(diào)試的方法(2023最新版)
Debugger for Unity是一個非正式支持的,官方推薦的,應(yīng)用最廣的,Visual Studio Code上的Unity調(diào)試插件,這篇文章主要介紹了VS?Code里使用Debugger?for?Unity插件進行調(diào)試(2023最新版),需要的朋友可以參考下2023-02-02
C#使用RegNotifyChangeKeyValue監(jiān)聽注冊表更改的方法小結(jié)
RegNotifyChangeKeyValue的最后一個參數(shù)傳遞false,表示以同步的方式監(jiān)聽,這篇文章主要介紹了C#使用RegNotifyChangeKeyValue監(jiān)聽注冊表更改的方法小結(jié),需要的朋友可以參考下2024-06-06
C#通過Win32API設(shè)置客戶端系統(tǒng)時間的方法詳解
在日常工作中,有時可能會需要獲取或修改客戶端電腦的系統(tǒng)時間,比如軟件設(shè)置了Licence有效期,本文以一個簡單的小例子,簡述如何通過C#獲取和設(shè)置客戶端電腦的系統(tǒng)時間,僅供學習分享使用,如有不足之處,還請指正,需要的朋友可以參考下2024-06-06
C#實現(xiàn)ListView選中項向上或向下移動的方法
這篇文章主要介紹了C#實現(xiàn)ListView選中項向上或向下移動的方法,通過兩個按鈕點擊事件實現(xiàn)ListView選中項的上下移動功能,需要的朋友可以參考下2015-06-06

