在C#中使用RESTful API的几种好方法

在C#中使用RESTful API的几种好方法

原文来自互联网,由长沙DotNET技术社区编译。 

通过Web开发的路径,您发现自己迟早需要处理外部API(应用程序编程接口)。在本文中,我的目标是列出在C#项目中使用RESTful API的方法的最全面列表,并通过一些简单示例向您展示如何做到这一点。

阅读该文章后,您将更深入地了解可以使用哪些选项,以及下次需要使用RESTful API[2]时如何选择正确的选项。

什么是RESTful API?

因此,在开始之前,您可能想知道API[3]代表什么,以及RESTful的全部含义是什么?

简而言之,API是软件应用程序之间的层。您可以将请求发送到API[4],并从中获得响应。API隐藏了软件应用程序具体实现的所有细节,并公开了您用于与该应用程序通信的接口。

整个互联网是由API组成的大型蜘蛛网。我们使用API在应用程序之间通信和关联信息。我们有一个API[5],可以处理几乎所有内容。您每天使用的大多数服务都有自己的API(GoogleMaps,Facebook,Twitter,Instagram,天气门户…)

RESTful部分意味着API是根据REST(表示状态传输)的原理和规则来实现的,REST是网络的基础架构原理。RESTful API在大多数情况下会返回纯文本,JSON或XML响应。更详细地解释REST不在本文的讨论范围之内,但是您可以在我们的文章REST API最佳实践中[6]阅读有关REST的更多信息。

如何使用RESTful API

好吧,让我们进入整个故事中最重要的部分。

有几种方法可以在C#中使用RESTful API:

HttpWebRequest/Response Class[7]WebClient Class[8]HttpClient Class[9]RestSharp NuGet Package[10]ServiceStack Http Utils[11]Flurl[12]DalSoft.RestClient[13]

这些中的每一个都有优点和缺点,因此让我们仔细研究它们,看看它们提供了什么。

例如,我们将通过GitHub API收集有关RestSharp回购版本及其发布日期的信息。此信息是公开可用的,您可以在此处查看原始JSON响应的外观: RestSharp版本[14]

我们将利用Json.NET库的帮助来反序列化获得的响应。同样,对于某些示例,我们将使用库的内置反序列化机制。选择哪种方式取决于您,因为没有正确的方法。(您可以在源代码中[15]看到这两种机制的实现)。

我期望通过接下来的几个示例得到一个反序列化JArray(为简单起见),其中包含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。

这个示例应该使您大致了解WebClientHttpWebRequestHttpWebResponse方法相比使用起来要容易得多。

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类还提供了许多其他有用的方法,使我们的生活更轻松。我们可以轻松地使用它来操作字符串,文件或字节数组,并且价格比HttpWebRequestHttpWebResponse方法要慢几毫秒。

无论是HttpWebRequestHttpWebResponseWebClient类在旧版本的.NET可供选择。如果您对其他产品感兴趣,请务必查看MSDN[16]WebClient

HttpClient类

HttpClient 是“新人”,它提供了旧库所缺乏的一些现代.NET功能。例如,您可以使用的单个实例发送多个请求HttpClient,它不绑定到特定的HTTP服务器或主机,而是使用async / await机制。

您可以在此视频中[17]找到使用HttpClient[18]的五个很好的理由[19]

•强类型标题。•共享缓存,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方法都应异步使用,应该以这种方式使用。

另外,我还要提到一件事。是否HttpClient应该包装在using块中还是在应用程序级别上进行静态讨论。尽管它实现了IDisposable,但似乎通过将它包装在using块中,会使应用程序出现故障并获得SocketException[20]而在ANKIT博客中,提供了基于很多有利于静态初始化的[21]HttpClient性能测试结果是。请务必阅读这些博客文章,因为它们可以帮助您更了解该HttpClient 库的正确用法。

并且不要忘记,由于是新的,HttpClient是.NET 4.5以上版本才有,因此在某些旧项目中使用它可能会遇到麻烦。

RestSharp

RestSharp是标准.NET库的OpenSource替代品,也是目前最酷的.NET库之一。它以NuGet软件包的形式提供,出于某些原因,您应该考虑尝试一下。

就像HttpClientRestSharp 一样,它是一个现代而全面的库,易于使用且令人愉悦,同时仍支持旧版本的.NET Framework。它具有内置的身份验证[22]和序列化/反序列化机制,[23]但允许您使用自定义机制[24]覆盖它们。它可跨平台使用,[25]并支持OAuth1,OAuth2,基本,NTLM和基于参数的身份验证。您可以选择同步或异步工作。该库还有很多其他功能,而这些只是它提供的众多好处中的一部分。有关RestSharp的用法和功能的详细信息,您可以访问GitHub上[26]的RestSharp 页面[27]

现在,让我们尝试使用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的反序列化机制,这有点浪费,但是我鼓励您使用它,因为它确实非常容易和方便。因此,您可以轻松地制作一个这样的容器:

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案例中要补充的最后一点是,其存储库需要维护者。如果您想了解更多有关这个很棒的库的信息,我敦促您前往RestSharp存储库[28],帮助该项目继续发展并变得更好。

ServiceStack Http实用程序

另一个库,但与RestSharp不同,ServiceStack似乎得到了适当维护,并与现代API[29]趋势保持同步。ServiceStack功能列表令人印象深刻,并且肯定具有各种应用程序。

在这里对我们最有用的是演示如何使用外部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;
}

如您所见,无论哪种方式都可以正常工作,并且您可以选择是获取字符串响应还是立即反序列化它。

尽管ServiceStack是我们偶然发现的最后一个库,但令我感到惊讶的是,它使用起来如此容易,而且我认为它将来可能成为我处理API和服务的首选工具。

Flurl

评论库中许多人要求的图书馆之一,并在Internet上受到许多人的喜爱,但仍吸引着人们。

Flurl代表Fluent Url Builder,这是库构建其查询的方式。对于不熟悉flurl的做事方式的人来说,flurl只是意味着库的构建方式是将方法链接在一起以实现更高的可读性,类似于人类语言。

为了使事情更容易理解,让我们举一些例子(这个例子来自官方文档):

// 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库的全部潜力。

如果您想了解更多有关如何在不同的现实生活场景使用Flurl,看看我们的 消费GitHub的API(REST)随着[31]Flurl[32] 文章

总而言之,它就像广告一样:易于使用,现代,可读性和可测试性。您对这个库还有什么期望?要开源?签[33]出: Flurl存储库[34],如果您愿意,可以贡献自己的力量!

DalSoft.RestClient

现在,此列表与该列表中的任何内容都有些不同。但这一点有所不同。

让我们看看如何使用DalSoft.RestClient来使用GitHub API,然后谈论我们已完成的工作。

首先,您可以通过输入以下内容,通过NuGet软件包管理器下载DalSoft.RestClient: Install-Package DalSoft.RestClient

或通过.NET Core CLI: dotnet add package DalSoft.RestClient

两种方法都可以。

拥有图书馆后,我们可以执行以下操作:

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在充分利用其功能的同时立即反序列化响应:

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;
}

因此,让我们稍微讨论一下这些例子。

乍一看,它似乎并不比我们使用的其他一些现代库简单得多。

但这归结为形成请求的方式,那就是利用RestClient的动态特性。例如,我们的BaseUrl是https://api.github.com ,我们需要进入https://api.github.com/repos/restsharp/restsharp/releases。我们可以通过动态创建客户端,然后通过链接Url的“部分”来形成Url来做到这一点:

await client.repos.restsharp.restsharp.releases.Get();

形成请求的一种非常独特的方法。还有一个非常灵活的!

因此,一旦我们设置了基本的网址,就可以轻松地使用不同的端点。

还值得一提的是,我们得到的JSON响应会自动进行类型转换。如您在第二个示例中看到的那样,我们方法的返回值是Task>. So,该库足够聪明,可以将响应转换为我们的类型(依赖于Json.NET)。这使我们的生活更加轻松。

除了易于理解和使用之外,DalSoft.RestClient还具有现代库应具备的所有功能。它是可配置的,异步的,可扩展的,可测试的,并且支持多个平台

我们仅演示了DalSoft.RestClient功能的一小部分。如果您对使用DalSoft.RestClient感兴趣,请转至我们的文章,[35]以学习如何在不同情况下使用它,或参阅 GitHub官方仓库[36]和文档[37]

其他选择

对于您的特定问题,还有许多其他选项可用。您可以使用任何这些库来使用特定的RESTful API。例如,octokit.net专门 [38]用于GitHub API,Facebook SDK[39] 用于使用Facebook API,并且还有许多其他功能可用于任何用途。

虽然这些库是专门为这些API而设计的,并且可能擅长于它们的用途,但它们的用途是有限的,因为您经常需要在应用程序中连接多个API[40]。这可能会导致每个实现都有不同的实现方式,以及更多的依赖关系,这可能导致重复并且容易出错。库越具体,其灵活性就越差。

GitHub上的源代码

GitHub上的源代码[41]

结论

因此,总而言之,我们已经讨论了可用于使用RESTful API的不同工具。我们已经提到了一些.NET库,可以这样做HttpWebRequestWebClientHttpClient,以及一些惊人的第三方工具,如RestSharp和ServiceStack。您还对这些工具进行了简短的介绍,并给出了一些非常简单的示例来向您展示如何开始使用它们。

我认为您现在至少有95%准备使用一些REST。继续展开翅膀,探索并找到更多有趣且有趣的方式来使用和连接不同的API。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/310263.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot自动装配源码解析

Spring Boot 自动装配原理 使用Spring Boot最方便的一点体验在于我们可以几零配置的搭建一个Spring Web项目&#xff0c;那么他是怎么做到不通过配置来对Bean完成注入的呢。这就要归功于Spring Boot的自动装配实现&#xff0c;他也是Spring Boot中各个Starter的实现基础&#…

自制 .NET Core 路由调试中间件

点击上方蓝字关注“汪宇杰博客”导语本文教大家如何在 .NET Core 应用中使用中间件输出路由信息以便调试程序。背景在 .NET Framework 的上古时代&#xff0c;有个叫做 RouteDebugger 的神器&#xff0c;可以在 MVC 或 Web API 应用中输出当前页面的路由信息&#xff0c;也可查…

玉柴spn码故障对照表_后处理的故障不总是尿素泵故障,也有可能是这些原因

之前说到后处理故障&#xff0c;解决的都是柴油机尿素泵、喷嘴的&#xff0c;而SCR箱同样是一个重要的部件&#xff0c;它的作用就是将尿素液与尾气中的氮氧化物充分混合并发生化学反应的场所&#xff0c;目前重卡SCR箱集SCR催化器和发动机排气消声器与一体。整体材料为不锈钢&…

SpringBoot中Bean按条件装配

Conditional条件装配 Conditional是Spring Framework提供的一个核心功能注解&#xff0c;这个注解的作用是提供自动装配的条件限制&#xff0c;一般我们在用Configuration&#xff0c;Bean的时候使用它。也就是我们在自定义Bean的注入的时候&#xff0c;我们可以通过Condition…

定义一个手表_华米Amazfit Pop评测:一款功能全面的“性价比”手表

目前的智能手表虽然品牌、型号众多&#xff0c;但基本可以分为二种类型&#xff1a;第一种为入门级智能手表&#xff0c;其功能单一与智能手环差不多&#xff0c;但胜在屏幕大、能够带来更好的观感且价格便宜&#xff1b;第二种为旗舰级智能手表&#xff0c;功能全面、硬件水准…

[Java基础]复制文件的异常处理try...catch...finally的做法

代码如下: package ErrorOperatorPack;import java.io.FileReader; import java.io.FileWriter; import java.io.IOException;public class CopyFileDemo01 {public static void main(String[] args){}private static void method() {FileReader fr null;FileWriter fw null…

有哪些你踏入社会才明白的道理

不知不觉已经工作10多年&#xff0c;从一个懵懂的大学生到被社会无情毒打&#xff0c;终于成长一个职场老鸟。最近几天在胡思乱想&#xff0c;这10多年不少认知和感悟&#xff0c;如果10年前有人能告诉我&#xff0c;我会不会少走很多很多弯路&#xff1f;读书的时候&#xff0…

手把手教你 git revert merge

开发中git分支管理 研发流程 从develop分支切出一个新分支&#xff0c;根据是功能还是bug&#xff0c;命名为id-xxx 或 id-fixbug-*。开发者完成开发&#xff0c;提交分支到远程仓库。开发者发起merge请求&#xff0c;将新分支请求merge到develop分支&#xff0c;并提醒code r…

如何把自己的经历写成小说_古天乐的经历教会我们:如何在被欺骗以后改善自己的心理状态...

众所周知&#xff0c;这个只有太阳能黑他的男人&#xff0c;早年未发迹时曾干过泊车小弟等工作&#xff0c;后来作为模特经纪人接触娱乐圈&#xff0c;传闻某次模特迟到&#xff0c;古爷临时救场&#xff0c;算是正式踏入娱圈&#xff0c;出现在无数大牌歌星的MV里&#xff0c;…

从GC的SuppressFinalize方法带你深刻认识Finalize底层运行机制

如果你经常看开源项目的源码&#xff0c;你会发现很多Dispose方法中都有这么一句代码&#xff1a; GC.SuppressFinalize(this); &#xff0c;看过一两次可能无所谓&#xff0c;看多了就来了兴趣&#xff0c;这篇就跟大家聊一聊。一&#xff1a;背景1. 在哪发现的相信现在Mysql在…

NIO工作方式浅析

java Socket 工作机制 Socket是描述计算机之前相互通信的一种抽象功能。通过基于TCP/IP的流套接字协议建立连接A机器B机器通信—建立Socket连接—通过TCP连接&#xff08;端口号指定唯一应用&#xff09;----IP寻址&#xff08;寻找唯一主机&#xff09;----最终找到唯一主机上…

bufferedimage生成的图片模糊_Kaptcha图片验证码工具

阅读文本大概需要3分钟。验证码的作用图片验证码自从诞生以来从未被抛弃&#xff0c;依然发出属于它所应有的光。验证码经常验证如下一些场景。1、用户登录&#xff0c;防止机器人登录2、论坛留言&#xff0c;防止恶意灌水3、短信验证码发送&#xff0c;防止盗刷短信Kaptcha 简…

[Java基础]对象(反)序列化流

对象序列化流: 代码如下: package ObjectOutputStreamPack;import java.io.Serializable;public class Student implements Serializable {private String name;private int age;public Student() {}public Student(String name, int age) {this.name name;this.age age;}pu…

C# 9 新特性:代码生成器、编译时反射

前言今天 .NET 官方博客宣布 C# 9 Source Generators 第一个预览版发布&#xff0c;这是一个用户已经喊了快 5 年特性&#xff0c;今天终于发布了。简介Source Generators 顾名思义代码生成器&#xff0c;它允许开发者在代码编译过程中获取查看用户代码并且生成新的 C# 代码参与…

I/O性能与可靠性

I/O调优 磁盘I/O优化 性能检测&#xff1a; 压力测试应用程序&#xff0c;观察系统I/O wait指标是否正常&#xff0c;例如有n个CPU&#xff0c;利息情况下I/O wait参数不超过25%&#xff0c;如果超过&#xff0c;就是这个程序的瓶颈就是在IO操作上了可以用iostat命令查看另外…

.NET开源工具类库:Masuit.Tools

【开源框架】| 通用工具类库这是恰童鞋骚年的第223篇原创文章本文介绍一个我的同事【懒得勤快】&#xff08;人称勤快哥&#xff0c;我们叫他骚哥&#xff09;写的一个.NET开源工具类库项目&#xff0c;包含一些常用的操作类&#xff0c;大都是静态类&#xff0c;加密解密&…

[Java基础]字节,字符打印流

代码如下&#xff1a; package PrintWriterPack;import java.io.FileNotFoundException; import java.io.PrintWriter;public class PrintWriterDemo {public static void main(String[] args) throws FileNotFoundException {PrintWriter pw new PrintWriter("D:\\Java…

javaI/O包中的包装模式

设计模式解析–适配器模式 对适配器模式功能比较好理解&#xff0c;就是讲一个类的接口换成客户端所能接受的另外一个接口&#xff0c;从而使两国接口不匹配而无法在一起工作的两个类能在一起工作。 适配器的结构 适配器UML图如下 Target&#xff08;目标接口&#xff09;&…