百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

C# RestSharp使用说明

csdh11 2025-02-10 11:57 20 浏览

介绍

RestSharp 的主要目的是通过 HTTP 对远程资源进行同步和异步调用。顾名思义,RestSharp 的主要受众是使用 REST API 的开发人员。但是,RestSharp 可以通过 HTTP(但不是 HTTP/2)调用任何 API,只要您拥有符合 W3C HTTP 标准的资源 URI 和要发送的请求参数。 .NET 开发人员使用 HTTP API 的主要挑战之一是处理不同类型的请求和响应,并将它们转换为复杂的 C# 类型。RestSharp 可以负责将请求正文序列化为 JSON 或 XML 并反序列化响应。它还可以根据不同的参数类型(路径、查询、表单或正文)形成有效的请求 URI。 查看[入门](
https://www.yuque.com/lengda/dyh56h/rgc1qp)页面以了解如何在您的应用程序中使用 RestSharp。

入门

在您的应用程序中使用 RestSharp 之前,您需要添加 NuGet 包。您可以使用 IDE 或命令行执行此操作:

dotnet add package RestSharp

基本用法

如果您只有少数一次性请求要向 API 发出,您可以像这样使用 RestSharp:

using RestSharp;
using RestSharp.Authenticators;

var client = new RestClient("https://api.twitter.com/1.1");
client.Authenticator = new HttpBasicAuthenticator("username", "password");

var request = new RestRequest("statuses/home_timeline.json", DataFormat.Json);

var response = client.Get(request);

IRestResponse 包含从远程服务器返回的所有信息。您可以访问标头、内容、HTTP 状态等。 我们建议使用通用重载,例如 Get 自动将响应反序列化为 .NET 类。

异步调用

所有同步方法都有它们对应的异步方法,后缀为 Async。 因此,您可以使用 GetAsync ExecuteAsync 代替返回 T Get 或返回 IRestResponseExecute。参数集通常是相同的。您可以选择提供取消标记,默认情况下设置为 CancellationToken.None。 例如:

using RestSharp;
using RestSharp.Authenticators;

var client = new RestClient("https://api.twitter.com/1.1");
client.Authenticator = new HttpBasicAuthenticator("username", "password");

var request = new RestRequest("statuses/home_timeline.json", DataFormat.Json);

var timeline = await client.GetAsync(request, cancellationToken);

然而,最重要的区别在于,以 HTTP 方法命名的异步方法返回的是 Task 而不是 Task>。因为这意味着如果请求失败,您将不会收到错误响应,所以这些方法会抛出异常。 但是,所有 ExecuteAsync 重载的行为方式都与Execute 相同并返回 IRestResponseIRestResponse。 在[此处](
https://www.yuque.com/lengda/dyh56h/sne7td)阅读有关 RestSharp 如何处理异常的信息。

内容类型

RestSharp 支持将 XML 或 JSON 正文作为请求的一部分发送。要将主体添加到请求中,只需调用 IRestRequest 实例的 AddJsonBodyAddXmlBody 方法即可。 使用这些方法时无需设置 Content-Type 或添加 DataFormat 参数到请求中,RestSharp 会为您完成。 RestSharp 还将处理 XML 和 JSON 响应并执行所有必要的反序列化任务,具体取决于服务器响应类型。因此,如果您想手动反序列化响应,您只需要添加 Accept 标头。 例如,您只需要这些行来发出携带 JSON 正文的请求:

var request = new RestRequest("address/update")
    .AddJsonBody(updatedAddress);
var response = await client.PostAsync(request);

响应

当您使用 ExecuteExecuteAsync 时,您将获得一个返回的具有 Content 属性的 IRestResponse 实例,其中包含字符串形式的响应。您可以在那里找到其他有用的属性,例如StatusCodeContentType 等等。如果请求不成功,您将收到一个响应,其 IsSuccessful 属性设置为 false 以及 ErrorExceptionErrorMessage 属性中解释的错误。 使用泛型 ExecuteExecuteAsync 时,您会得到一个返回的 IRestResponse 实例,它与 IRestResponse 相同,但还包含反序列化响应后的 T Data 属性。 像 GetGetAsync 扩展不会返回整个 IRestResponse,而只是一个反序列化的响应。如果出现问题,您可能会得到返回 null,并且可能很难理解问题原因。因此,在使用泛型扩展方法时,我们建议将
IRestClient.ThrowOnAnyError
属性设置为 true。通过这样做,您告诉 RestSharp 在出现问题时抛出异常。然后,您可以将调用包装在 try/catch 块中并相应地处理异常。要了解有关 RestSharp 如何处理异常的更多信息,请参阅[异常处理](
https://www.yuque.com/lengda/dyh56h/sne7td)页面。

推荐用法

RestSharp 最适合作为 API 代理类的基础。以下是来自[Twilio](
http://github.com/twilio/twilio-csharp)库的几个示例。 创建一个类以包含您的 API 代理实现,并使用
Execute 方法将所有请求汇集到 API。这允许您设置跨请求共享的常用参数和其他设置(如身份验证)。因为每个请求都需要帐户 ID 和密钥,所以在创建代理的新实例时,您需要传递这两个值。

警告 请注意,`Execute` 不会抛出异常,但在 `ErrorException` 属性中可用。

// TwilioApi.cs
public class TwilioApi 
{
    const string BaseUrl = "https://api.twilio.com/2008-08-01";

    readonly IRestClient _client;

    string _accountSid;

    public TwilioApi(string accountSid, string secretKey) 
    {
        _client = new RestClient(BaseUrl);
        _client.Authenticator = new HttpBasicAuthenticator(accountSid, secretKey);
        _accountSid = accountSid;
    }

    public T Execute(RestRequest request) where T : new()
    {
        request.AddParameter("AccountSid", _accountSid, ParameterType.UrlSegment); // used on every request
        var response = _client.Execute(request);

        if (response.ErrorException != null)
        {
            const string message = "Error retrieving response.  Check inner details for more info.";
            var twilioException = new Exception(message, response.ErrorException);
            throw twilioException;
        }
        return response.Data;
    }
}

接下来,定义一个映射到 API 返回的数据的类。

// Call.cs
public class Call
{
 public string Sid { get; set; }
 public DateTime DateCreated { get; set; }
 public DateTime DateUpdated { get; set; }
 public string CallSegmentSid { get; set; }
 public string AccountSid { get; set; }
 public string Called { get; set; }
 public string Caller { get; set; }
 public string PhoneNumberSid { get; set; }
 public int Status { get; set; }
 public DateTime StartTime { get; set; }
 public DateTime EndTime { get; set; }
 public int Duration { get; set; }
 public decimal Price { get; set; }
 public int Flags { get; set; }
}

然后添加一个方法来查询 API 以获取特定 Call 资源的详细信息。

// TwilioApi.cs, GetCall method of TwilioApi class
public Call GetCall(string callSid) 
{
 var request = new RestRequest("Accounts/{AccountSid}/Calls/{CallSid}");
 request.RootElement = "Call";

 request.AddParameter("CallSid", callSid, ParameterType.UrlSegment);

 return Execute(request);
}

这里有一些 RestSharp 负责处理的魔法,所以你不必做。 API 返回 XML,使用默认的 XmlDeserializer xml 被自动检测并反序列化为 Call 对象。默认情况下, RestRequest 是通过 GET HTTP 请求进行的。您可以通过设置 RestRequestMethod 属性,或在创建实例时在构造函数中指定方法,来更改此设置(如下所述)。类型参数的 UrlSegment 值根据存在于 Resource 属性值中的匹配标记名称注入到 URL 中。因为 AccountSid 对每个请求都是通用的,所以把它设置在 TwilioApi.Execute。我们指定要开始反序列化的根元素的名称。在这种示例中,返回的 XML 是 ...,并且既然 Response 元素本身不包含任何与我们的模型相关的信息,我们从树的下一步开始反序列化。 您还可以发出 POST(和 PUT/DELETE/HEAD/OPTIONS)请求:

// TwilioApi.cs, method of TwilioApi class
public Call InitiateOutboundCall(CallOptions options) 
{
 Require.Argument("Caller", options.Caller);
 Require.Argument("Called", options.Called);
 Require.Argument("Url", options.Url);

 var request = new RestRequest("Accounts/{AccountSid}/Calls", Method.POST);
 request.RootElement = "Calls";

 request.AddParameter("Caller", options.Caller);
 request.AddParameter("Called", options.Called);
 request.AddParameter("Url", options.Url);

 if (options.Method.HasValue) request.AddParameter("Method", options.Method);
 if (options.SendDigits.HasValue()) request.AddParameter("SendDigits", options.SendDigits);
 if (options.IfMachine.HasValue) request.AddParameter("IfMachine", options.IfMachine.Value);
 if (options.Timeout.HasValue) request.AddParameter("Timeout", options.Timeout.Value);

 return Execute(request);
}

此示例还演示了 RestSharp 的轻量级验证帮助程序。这些帮助程序允许您在发出请求之前验证提交的值是否有效。在此处阅读有关验证的更多信息。 本示例中所有通过 AddParameter 添加的值都将作为标准编码表单提交,类似于通过网页提交的表单。如果是 GET 样式的请求(GET/DELETE/OPTIONS/HEAD),则参数值将通过查询字符串提交。您还可以使用 AddParameter 添加标头和 cookie 参数。要将对象的所有属性添加为参数,请使用 AddObject。要添加要上传的文件,请使用 AddFile(请求将作为多部分编码形式发送)。要包含 XML 或 JSON 之类的请求正文,请使用 AddXmlBodyAddJsonBody

序列化

RestSharp 内置了 JSON 和 XML 序列化器,无需任何额外的包或配置。还有一些 JSON 序列化程序作为附加包提供。

提示 RestSharp 的默认行为是吞下反序列化错误并在响应的 Data 属性中返回 null。在[错误处理](
https://www.yuque.com/lengda/dyh56h/sne7td)中阅读更多关于它的信息。?

默认序列化程序

RestSharp 核心包包括一些用于 JSON 和 XML 格式的默认序列化程序。

JSON

默认的 JSON 序列化程序使用 SimpleJson 的分支版本。它非常简单,在许多情况下无法处理高级场景。我们不打算修复或添加新功能到默认 JSON 序列化器,因为它已经处理了很多情况,当您需要处理更复杂的对象时,请考虑使用下面提到的可选的 JSON 序列化器。? 有一个[已知问题](
https://github.com/restsharp/RestSharp/issues/1433),当使用常规的 .NET 日期格式(
yyyy-MM-ddTHH:mm:ssZ)时,SimpleJson 不使用 UTC 时区。正如问题中所建议的,可以通过为 SimpleJson 显式设置日期格式来解决:?

client.UseSerializer(
    () => new JsonSerializer { DateFormat = "yyyy-MM-ddTHH:mm:ss.FFFFFFFZ" }
);

XML

您可以使用默认的 XML 序列化程序或 DotNetXmlSerializer,后者使用 .NET 的 System.Xml.Serialization 库。要使用 DotNetXmlSerializer 您需要配置 REST 客户端实例:?

client.UseDotNetXmlSerializer();

NewtonsoftJson(又名Json.NET)

NewtonsoftJson 包是最流行的 .NET JSON 序列化程序。它处理所有可能的场景并且非常可配置。这种灵活性伴随着性能成本。如果您需要一些速度更快的,请查看 Utf8JsonSystem.Text.Json 序列化程序(如下)。 RestSharp 通过单独的包支持 Json.Net 序列化程序。您可以从 NuGet 安装它:

dotnet add package RestSharp.Serializers.NewtonsoftJson

使用包提供的扩展方法来配置客户端:

client.UseNewtonsoftJson();

序列化器配置了一些默认选项:

JsonSerializerSettings DefaultSettings = new JsonSerializerSettings
{
 ContractResolver     = new CamelCasePropertyNamesContractResolver(),
 DefaultValueHandling = DefaultValueHandling.Include,
 TypeNameHandling     = TypeNameHandling.None,
 NullValueHandling    = NullValueHandling.Ignore,
 Formatting           = Formatting.None,
 ConstructorHandling  = ConstructorHandling.AllowNonPublicDefaultConstructor
};

如果您需要使用不同的设置,您可以提供您的 JsonSerializerSettings 实例作为扩展方法的参数。?

Utf8json

众所周知,Utf8Json 包是最快的 .NET JSON 序列化程序。 RestSharp 通过单独的包支持 Utf8Json 序列化程序。您可以从 NuGet 安装它:

dotnet add package RestSharp.Serializers.Utf8Json

使用扩展方法配置您的 REST 客户端:

client.UseUtf8Json();

不带参数调用扩展方法时,会配置默认选项: - 允许私有属性 - 排除空值 - 使用驼峰式 如果需要使用不同的选项,可以提供 IJsonFormatterResolver 实例作为扩展方法的参数。

警告 请记住,默认情况下,此序列化程序区分大小写。

System.Text.Json

Microsoft 将新的 JSON 序列化程序包 System.Text.Json 包含在 .NET Core 3 内。它是一个小型且快速的序列化程序,默认情况下用于 .NET Core 3 及更高版本的 WebApi 版本。该包也可用于 .NET Standard 2.0 和 .NET Framework 4.6.1 及更高版本。 RestSharp 通过单独的包支持 System.Text.Json 序列化程序。您可以从 NuGet 安装它:

dotnet add package RestSharp.Serializers.SystemTextJson

使用扩展方法配置您的 REST 客户端:

client.UseSystemTextJson();

除非您向扩展方法提供自己的 JsonSerializerOptions 实例,否则序列化程序将使用默认选项。?

警告 请记住,默认情况下,此序列化程序区分大小写。

自定义

您还可以实现自定义序列化程序。要同时支持序列化和反序列化,您必须实现该 IRestSerializer 接口。 这是一个使用 System.Text.Json 自定义序列化程序的示例:

public class SimpleJsonSerializer : IRestSerializer
{
 public string Serialize(object obj) => JsonSerializer.Serialize(obj);

 public string Serialize(Parameter bodyParameter) => Serialize(bodyParameter.Value);

 public T Deserialize(IRestResponse response) => JsonSerializer.Deserialize(response.Content);

 public string[] SupportedContentTypes { get; } =
 {
   "application/json", "text/json", "text/x-json", "text/javascript", "*+json"
 };

 public string ContentType { get; set; } = "application/json";

 public DataFormat DataFormat { get; } = DataFormat.Json;
}

SupportedContentTypes 属性的值将和响应 Content-Type 标头一起用于匹配序列化程序。 ContentType 属性将在发出请求时使用,以便服务器知道如何处理有效负载。

处理文件

这是一个示例,它将使用 Stream 来避免请求内容的内存缓冲。在检索将立即写入磁盘的大量数据时很有用。

var tempFile = Path.GetTempFileName();
using var writer = File.OpenWrite(tempFile);

var client = new RestClient(baseUrl);
var request = new RestRequest("Assets/LargeFile.7z");
request.ResponseWriter = responseStream =>
{
 using (responseStream)
    {
 responseStream.CopyTo(writer);
    }
};
var response = client.DownloadData(request);

鉴权

RestSharp 包括用于基本 HTTP(授权标头)、NTLM 和基于参数的系统的鉴权。

使用 SimpleAuthenticator

SimpleAuthenticator 允许传递用户名和密码(或API和密钥)作为请求方法的 GET 或 POST 参数。您将用户名、密码和每个参数的名称传递给它。?

var client = new RestClient("http://example.com");
client.Authenticator = new SimpleAuthenticator("username", "foo", "password", "bar");

var request = new RestRequest("resource", Method.GET);
client.Execute(request);

为此请求生成的 URL 将是
http://example.com/resource?username=foo&password=bar
将上述请求更改为使用 POST 或 PUT 会将值作为编码的表单值发送。

基本认证

OAuth1

JWT

自定义鉴权

您可以通过 IAuthenticator 来编写自己的实现,并在您的 RestClient 中注册:?

var client = new RestClient();
client.Authenticator = new SuperAuthenticator(); // implements IAuthenticator

Authenticate 方法是调用 RestClient.ExecuteRestClient.Execute 时调用的第一件事。Authenticate 方法是通过当前正在执行的 RestRequest 提供请求数据的每一个部分(头,参数等)的访问。

请求参数

创建 RestRequest 之后,您可以向其添加参数。这是使用默认 IHttp 实现时当前支持的 5 种类型及其行为的描述。

Cookie

将参数添加到与请求一起发送的 cookie 列表中。cookie 名称是参数的名称,值是您传入的 Value.ToString()。

Http Header

添加参数作为与请求一起发送的 HTTP 标头。header 名称是参数的名称,header 值是参数的值。 请注意,有一些受限制的标头可能表现不同或被简单地忽略。请查看 _restrictedHeaderActions 字典 Http.cs 以了解哪些 header 是特殊的以及它们的行为方式。

Get 或 Post

这取决于方法的不同表现。如果您执行 GET 调用,RestSharp 会将参数以 url?name1=value1&name2=value 的形式附加到 Url 中。 在 POST 或 PUT 请求中,这取决于您是否有文件附加到请求中。如果没有,参数将作为请求的正文以 name1=value1&name2=value2 的形式发送。此外,请求将作为
application/x-www-form-urlencoded 发送。 在这两种情况下,名称和值都将自动进行 url 编码。 如果您有文件,RestSharp 将发送 multipart/form-data 请求。您的参数将以如下形式作为此请求的一部分:

Content-Disposition: form-data; name="parameterName"

ParameterValue

Url 分段

与 GetOrPost 不同, ParameterType 替换 RequestUrl 中的占位符值:

var request = new RestRequest("health/{entity}/status")
    .AddUrlSegment("entity", "s2");

当请求执行时,RestSharp 将尝试用该名称的参数(不带 {} )匹配 {placeholder} 与并将其替换为值。所以上面的代码结果是 url health/s2/status。

请求体

如果设置了这个参数,它的值将作为请求的正文发送。只有一个 RequestBody 参数会被接受——第一个。 参数的名称将用作 Content-Type 请求标头。 RequestBody 不适用于 GET 或 HEAD 请求,因为它们不发送正文。 如果您也有 GetOrPost 参数,它们将覆盖 RequestBody ——RestSharp 不会组合它们,而是将 RequestBody 参数扔掉。 我们推荐使用 AddJsonBody 或 AddXmlBody 方法而不是使用 AddParameter 携带类型 BodyParameter。这些方法将设置正确的请求类型并为您执行序列化工作。

AddJsonBody

当您调用 AddJsonBody 时,它会为您执行以下操作: - 指示 RestClient 在发出请求时将对象参数序列化为 JSON - 将内容类型设置为 application/json - 将请求正文的内部数据类型设置为 DataType.Json 不要设置内容类型标头或发送 JSON 字符串或某种 JObject 实例到 AddJsonBody ,它不会工作! 示例如下:

var param = new MyClass { IntData = 1, StringData = "test123" };
request.AddJsonBody(param);

AddXmlBody

当您调用 AddXmlBody 时,它会为您执行以下操作: - 指示 RestClient 在发出请求时将对象参数序列化为 XML - 将内容类型设置为 application/xml - 将请求正文的内部数据类型设置为 DataType.Xml 不要设置内容类型标头或将 XML 字符串发送到 AddXmlBody ,它不会工作!

Query String

这与 GetOrPost 类似,不同之处在于它总是将参数以 url?name1=value1&name2=value2 的形式附加到 url,而不管请求方法如何。 例子:

var client = new RestClient("https://search.me");
var request = new RestRequest("search")
    .AddParameter("foo", "bar");
var response = await client.GetAsync(request);

它将发送 GET 请求到 https://search.me/search?foo=bar 。 您还可以明确指定查询字符串参数类型:

request.AddParameter("foo", "bar", ParameterType.QueryString);

在某些情况下,您可能需要阻止 RestSharp 对查询字符串参数进行编码。为此,请使用 QueryStringWithoutEncode 参数类型。

异常处理

如果存在网络传输错误(网络关闭、DNS 查找失败等)或任何类型的服务器错误(404 除外),
RestResponse.ResponseStatus 将设置为 ResponseStatus.Error,否则为 ResponseStatus.Completed。 如果 API 返回 404,ResponseStatus 仍将是 Completed 。如果您需要访问返回的 HTTP 状态代码,您可以在 RestResponse.StatusCode 中找到它。 Status 属性是独立于 API 异常处理的完成指示符。 通常,如果请求失败,RestSharp 不会抛出异常。 然而,可以配置 RestSharp 在不同情况下抛出。


追求更好阅读体验的同学推荐查看本人语雀原文,链接如下:

C# RestSharp使用说明 · 语雀

相关推荐

探索Java项目中日志系统最佳实践:从入门到精通

探索Java项目中日志系统最佳实践:从入门到精通在现代软件开发中,日志系统如同一位默默无闻却至关重要的管家,它记录了程序运行中的各种事件,为我们排查问题、监控性能和优化系统提供了宝贵的依据。在Java...

用了这么多年的java日志框架,你真的弄懂了吗?

在项目开发过程中,有一个必不可少的环节就是记录日志,相信只要是个程序员都用过,可是咱们自问下,用了这么多年的日志框架,你确定自己真弄懂了日志框架的来龙去脉嘛?下面笔者就详细聊聊java中常用日志框架的...

物理老师教你学Java语言(中篇)(物理专业学编程)

第四章物质的基本结构——类与对象...

一文搞定!Spring Boot3 定时任务操作全攻略

各位互联网大厂的后端开发小伙伴们,在使用SpringBoot3开发项目时,你是否遇到过定时任务实现的难题呢?比如任务调度时间不准确,代码报错却找不到方向,是不是特别头疼?如今,随着互联网业务规模...

你还不懂java的日志系统吗 ?(java的日志类)

一、背景在java的开发中,使用最多也绕不过去的一个话题就是日志,在程序中除了业务代码外,使用最多的就是打印日志。经常听到的这样一句话就是“打个日志调试下”,没错在日常的开发、调试过程中打印日志是常干...

谈谈枚举的新用法--java(java枚举的作用与好处)

问题的由来前段时间改游戏buff功能,干了一件愚蠢的事情,那就是把枚举和运算集合在一起,然后运行一段时间后buff就出现各种问题,我当时懵逼了!事情是这样的,做过游戏的都知道,buff,需要分类型,且...

你还不懂java的日志系统吗(javaw 日志)

一、背景在java的开发中,使用最多也绕不过去的一个话题就是日志,在程序中除了业务代码外,使用最多的就是打印日志。经常听到的这样一句话就是“打个日志调试下”,没错在日常的开发、调试过程中打印日志是常干...

Java 8之后的那些新特性(三):Java System Logger

去年12月份log4j日志框架的一个漏洞,给Java整个行业造成了非常大的影响。这个事情也顺带把log4j这个日志框架推到了争议的最前线。在Java领域,log4j可能相对比较流行。而在log4j之外...

Java开发中的日志管理:让程序“开口说话”

Java开发中的日志管理:让程序“开口说话”日志是程序员的朋友,也是程序的“嘴巴”。它能让程序在运行过程中“开口说话”,告诉我们它的状态、行为以及遇到的问题。在Java开发中,良好的日志管理不仅能帮助...

吊打面试官(十二)--Java语言中ArrayList类一文全掌握

导读...

OS X 效率启动器 Alfred 详解与使用技巧

问:为什么要在Mac上使用效率启动器类应用?答:在非特殊专业用户的环境下,(每天)用户一般可以在系统中进行上百次操作,可以是点击,也可以是拖拽,但这些只是过程,而我们的真正目的是想获得结果,也就是...

Java中 高级的异常处理(java中异常处理的两种方式)

介绍异常处理是软件开发的一个关键方面,尤其是在Java中,这种语言以其稳健性和平台独立性而闻名。正确的异常处理不仅可以防止应用程序崩溃,还有助于调试并向用户提供有意义的反馈。...

【性能调优】全方位教你定位慢SQL,方法介绍下!

1.使用数据库自带工具...

全面了解mysql锁机制(InnoDB)与问题排查

MySQL/InnoDB的加锁,一直是一个常见的话题。例如,数据库如果有高并发请求,如何保证数据完整性?产生死锁问题如何排查并解决?下面是不同锁等级的区别表级锁:开销小,加锁快;不会出现死锁;锁定粒度...

看懂这篇文章,你就懂了数据库死锁产生的场景和解决方法

一、什么是死锁加锁(Locking)是数据库在并发访问时保证数据一致性和完整性的主要机制。任何事务都需要获得相应对象上的锁才能访问数据,读取数据的事务通常只需要获得读锁(共享锁),修改数据的事务需要获...