在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:
- HttpWebRequest/Response类
- WebClient类
- HttpClient类
- RestSharp
- ServiceStack Http实用程序
- Flurl
- DalSoft.RestClient
 这些中的每一个都有优点和缺点,因此让我们仔细研究它们,看看它们提供了什么。
例如,我们将通过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的五个很好的理由:
- 强类型标题。
- 共享缓存,cookie和凭据
- 访问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;
    }
}
另外,我还要提到一件事。是否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做了简单的展示,易于使用,现代,可读性和可测试性。
在C#中使用RESTful API的几种好方法的更多相关文章
- C语言中返回字符串函数的四种实现方法                                        2015-05-17 15:00    23人阅读    评论(0)    收藏
		C语言中返回字符串函数的四种实现方法 分类: UNIX/LINUX C/C++ 2010-12-29 02:54 11954人阅读 评论(1) 收藏 举报 语言func存储 有四种方式: 1.使用堆空 ... 
- C语言中返回字符串函数的四种实现方法
		转自C语言中返回字符串函数的四种实现方法 其实就是要返回一个有效的指针,尾部变量退出后就无效了. 有四种方式: 1.使用堆空间,返回申请的堆地址,注意释放 2.函数参数传递指针,返回该指针 3.返回函 ... 
- Swagger2在DBA Service中生成RESTful API的实践
		目的与背景: 目的:对外暴露DBA Service必要的RESTful API,形成规整的API文档 背景:DBA Service后端采用Spring-boot,属于Spring家族,故生成API的工 ... 
- C语言中结构体(struct)的几种初始化方法
		转自https://www.jb51.net/article/91456.htm 本文给大家总结的struct数据有3种初始化方法 1.顺序 2.C风格的乱序 3.C++风格的乱序 下面通过示 ... 
- 使用Swagger2构建SpringMVC项目中的Restful API文档
		使用Swagger自动生成API文档,不仅增加了项目的可维护性,还提高了API的透明度更利于快速测试等工作,便于更快地发现和解决问题. 本篇文章只记录整合过程,关于Security Configura ... 
- 只需一步,在Spring Boot中统一Restful API返回值格式与统一处理异常
		## 统一返回值 在前后端分离大行其道的今天,有一个统一的返回值格式不仅能使我们的接口看起来更漂亮,而且还可以使前端可以统一处理很多东西,避免很多问题的产生. 比较通用的返回值格式如下: ```jav ... 
- Struts2中获取servlet API的几种方式
		struts2是一个全新的MVC框架,如今被广大的企业和开发者所使用,它的功能非常强大.这给我们在使用servlet 纯java代码写项目的时候带来了福音.但是一般来说,我们的项目不到一定规模并不需要 ... 
- Struts 2中访问Servlet API的几种方法小结
		1.使用ActionContext Action运行期间所用到的数据都保存在ActionContext中,例如session.客户端提交的参数等,ActionContext是Action的一个上下文对 ... 
- 拦截Restful API的三种方式
		如题, 方式有三种. (1). 过滤器filter javaEE规范 (2). 拦截器interceptor springmvc提供 (3). 切片 aspect 一. Filter使用示例 impo ... 
随机推荐
- winform应用如何发布(不用打包)、并提醒用户自动更新
			环境:VS2019 community C# winform 应用程序 设计应用程序界面 编写对应代码 使用PS设计程序标识ICON F4打开属性: 设置ICON 设置背景 打开项目属性 打开“发 ... 
- HDU4192 Guess the Numbers(表达式计算、栈)
			题意: 给你一个带括号.加减.乘的表达式,和n个数$(n\leq 5)$,问你带入这几个数可不可能等于n 思路: 先处理表达式:先将中缀式转化为逆波兰表达式 转换过程需要用到栈,具体过程如下:1)如果 ... 
- 在.NET Core中使用MachineKey
			在.NET Core中使用MachineKey 姐妹篇:<ASP.NET Cookie是怎么生成的> 姐妹篇:<.NET Core验证ASP.NET密码> 在上篇文章中,我介绍 ... 
- 仅仅知道如何终止XHR请求,或许对你来说是不够的!
			TLDR: 当我们需要的时候,我们可以通过AbortController接口来终止一个或者多个请求. 前言 到目前为止,我们有两个常用的基本的手段去发送请求进而局部刷新页面内容,其一是XMR(XMLH ... 
- qt creator源码全方面分析(2-3)
			目录 External Tool Specification Files 文件名 位置 文件格式 主要标签 描述标签 可执行规范标签 示例 External Tool Specification Fi ... 
- php面试笔记(3)-php基础知识-运算符
			本文是根据慕课网Jason老师的课程进行的PHP面试知识点总结和升华,如有侵权请联系我进行删除,email:guoyugygy@163.com 在面试中,考官往往喜欢基础扎实的面试者,而运算符相关的考 ... 
- 详解CopyOnWrite容器及其源码
			详解CopyOnWrite容器及其源码 在jave.util.concurrent包下有这样两个类:CopyOnWriteArrayList和CopyOnWriteArraySet.其中利用到了Cop ... 
- CodeForces 429B	Working out   DP
			E - Working out Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Su ... 
- -bash: warning: setlocale: LC_CTYPE: cannot change locale (zh_CN.UTF-8mb4): No such file or directory
			前几天登录服务器发现出现了这些个警告,一直没时间去处理他,今天难得有空,处理一下并记录下来,希望可以帮助到有需要的朋友. 警告信息如下: Last login: Tue May :: from 192 ... 
- while 循环 实例
			/*int i=0; while(i<100){// 循环条件 while先执行后循环 printf("while第%d遍循环体\n",i);//循环体 i++; } */ ... 
