RestSharp 请求构建完全指南:从参数、请求体到文件上传
2026/9/24 15:08:04 网站建设 项目流程
  • 后端
  • API设计

【免费下载链接】RestSharp

Simple REST and HTTP API Client for .NET

项目地址:https://gitcode.com/gh_mirrors/re/RestSharp
点击查看免费下载

导读

本文以 RestSharp v1.13 官方文档 usage/request.md 为骨架,系统讲解如何构建一个RestRequest实例:包括创建请求、添加各类参数(Header、GetOrPost、QueryString、UrlSegment、Cookie)、使用AddObject/AddObjectStatic批量映射对象属性、构造 JSON / XML / 字符串请求体以及上传文件等完整流程。读完本文,你将掌握 RestSharp 请求构建的每一种参数类型的语义、行为差异与底层实现,能够直接编写可运行的 REST 客户端代码。

创建请求:从 resource 到 Method

RestSharp 中所有请求都围绕RestRequest展开。使用RestClient发起请求之前,必须先创建一个请求实例:

var request = new RestRequest(resource); // resource 是相对于客户端 BaseUrl 的子路径

resource是客户端基础地址的子路径。从源码可见,RestRequest的默认构造函数将方法设为Method.Get(见 RestRequest.cs),因此默认请求类型是 GET。你可以通过设置Method属性覆盖,也可以直接用构造函数重载指定:

var request = new RestRequest(resource, Method.Post);

构造函数签名对应源码中的RestRequest(string? resource, Method method = Method.Get)(见 RestRequest.cs)。此外还有接受Uri的重载:若传入绝对 URI,则以AbsoluteUri作为 resource;若为相对 URI,则取其OriginalString(见 RestRequest.cs)。

一个值得注意的细节:当resource字符串中带有查询串(如search?foo=bar)时,构造函数会自动解析该查询串并转换为QueryParameter加入请求,同时把Resource还原为不含查询串的部分(见 RestRequest.cs)。

请求创建后,就可以向它添加各类参数。RestSharp 支持的参数类型与用途如下表:

参数类型添加方式作用位置说明
HeaderParameterAddHeaderHTTP 头随请求发送的请求头
GetOrPostParameterAddParameterURL 或请求体按 HTTP 方法决定去向
QueryParameterAddQueryParameterURL 查询串始终追加到 URL
UrlSegmentParameterAddUrlSegmentURL 路径占位符替换{placeholder}
CookieAddCookieCookie 头请求级 Cookie
BodyParameter / JsonParameter / XmlParameterAddJsonBody/AddXmlBody/AddStringBody/AddBody请求体请求正文

Request headers:请求头

Header 参数以参数名为头名、参数值为头值,作为 HTTP 头随请求发送。常用的添加方法有三个:

AddHeader(string name, string value); AddHeader<T>(string name, T value); // value 会被转换为字符串 AddOrUpdateHeader(string name, string value); // 已存在同名头时直接替换

用法示例:

var request = new RestRequest("/path").AddHeader("X-Key", someKey);

从源码看,AddHeader(string, string)内部创建HeaderParameter(见 RestRequestExtensions.Headers.cs),AddOrUpdateHeader则通过AddOrUpdateParameter替换同名已有参数(见 RestRequestExtensions.Headers.cs)。泛型重载AddHeader<T>要求T : struct,值会按指定的 culture(默认InvariantCulture)格式化为字符串(见 RestRequestExtensions.Headers.cs)。若需要批量添加,还有AddHeaders/AddOrUpdateHeaders,它们会先检查是否存在重复键(大小写不敏感),有重复则抛出ArgumentException(见 RestRequestExtensions.Headers.cs)。

RestSharp 在调用资源时会自动区分请求头与内容头(content headers)。你也可以把 Header 参数加在客户端上,这样每次请求都会带上——非常适合鉴权头等公共头:

client.AddDefaultHeader(string name, string value);

源码中AddDefaultHeader实现在 RestClient.Extensions.Params.cs,它同样以HeaderParameter加入客户端默认参数集合。

:::warning 避免手动设置 Content-Type 头 RestSharp 默认会使用正确的内容类型。除非你非常确定需要,否则不要手动给请求添加Content-Type头;如需自定义内容类型,请直接设置到 body 参数 本身。 :::

Get or Post parameters:默认参数类型

GetOrPostParameter是 RestSharp 的默认参数类型,通过AddParameter添加:

request .AddParameter("name1", "value1") .AddParameter("name2", "value2");

GetOrPost的行为随 HTTP 方法而变化:

  • GET 请求:参数追加到 URL,形如url?name1=value1&name2=value2
  • POST / PUT 请求:取决于请求是否携带文件:
    • 无文件时,参数以name1=value1&name2=value2的形式作为请求体发送,Content-Type 为application/x-www-form-urlencoded
    • 有文件时,发送multipart/form-data请求,每个参数以如下形式出现在 multipart 中:
Content-Type: text/plain; charset=utf-8 Content-Disposition: form-data; name="parameterName" ParameterValue

两种情况下,参数名与参数值默认都会被 URL 编码,除非显式指定不编码:

request.AddParameter("name", "Væ üé", false); // 不编码 value

在 multipart 表单调用中,有时需要覆盖参数默认的内容类型,可通过设置参数对象的ContentType属性实现。下面的代码创建一个值为 JSON 的 POST 参数,并指定适当的内容类型:

var parameter = new GetOrPostParameter("someJson", "{\"attributeFormat\":\"pdf\"}") { ContentType = "application/json" }; request.AddParameter(parameter);

当请求使用 multipart 内容时,该参数将携带指定内容类型发送:

Content-Type: application/json; charset=utf-8 Content-Disposition: form-data; name="someJson" {"attributeFormat":"pdf"}

GetOrPost参数同样可以注册为客户端默认参数,从而附加到该客户端发起的每个请求:

client.AddDefaultParameter("foo", "bar");

其行为与请求级参数完全一致,只是作用于全部请求。

Query string:查询串参数

QueryStringGetOrPost类似,但无论请求方法是什么,始终把参数以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<SearchResponse>(request);

该代码会向https://search.me/search?foo=bar发送 GET 请求。对于 POST 风格的请求,则需要显式添加查询串参数:

request.AddQueryParameter("foo", "bar");

AddQueryParameter内部创建QueryParameterencode参数默认为true(见 RestRequestExtensions.Query.cs)。有时需要禁止 RestSharp 对查询串参数编码,将encode参数设为false即可:

request.AddQueryParameter("foo", "bar/fox", false);

与前述类型一致,查询串参数也可注册为客户端默认参数:

client.AddDefaultQueryParameter("foo", "bar");

上面这行代码会使该客户端实例发起的所有请求都在查询串中携带foo=bar。其底层实现在 RestClient.Extensions.Params.cs,以QueryParameter形式加入默认参数集合。

Using AddObject:把对象属性批量映射为参数

如果你有一组参数需要一次性添加,可以先把它们收集进一个对象,再调用AddObject

var params = new { status = 1, priority = "high", ids = new [] { "123", "456" } }; request.AddObject(params);

它等价于:

request.AddParameter("status", 1); request.AddParameter("priority", "high"); request.AddParameter("ids", "123,456");

注意,AddObject只支持基本类型(primitive)属性,也支持如上所示的基本类型集合。从源码看,AddObject通过反射获取对象属性,然后逐个调用AddParameter(prop.Name, prop.Value, prop.Encode)(见 RestRequestExtensions.Object.cs)。它还有可选参数includedProperties,用于指定只提取哪些属性。

如果需要覆盖属性名或格式,可以使用RequestProperty特性:

public class RequestModel { // 覆盖名称与格式 [RequestProperty(Name = "from_date", Format = "d")] public DateTime FromDate { get; set; } } // 添加到请求 request.AddObject(new RequestModel { FromDate = DateTime.Now });

此时请求会得到一个名为from_date的 GET 或 POST 参数,值为当前日期的短日期格式。RequestPropertyAttribute定义在 ObjectParser.cs,支持Name(重命名)、FormatDateTime/数值格式化字符串)、ArrayQueryType(数组序列化方式,默认CommaSeparated,可设为ArrayParameters以生成name[]形式)、Encode(是否编码,默认true)四个属性。

Using AddObjectStatic:预编译表达式的高性能版本

AddObjectStatic<T>(...)使用预编译表达式来获取属性值,与每次调用都走反射的AddObject相比,它会把“从类型T的对象中取属性”的函数缓存起来,因此快得多

AddObjectStatic支持自定义参数名与格式,也支持传入属性名单,指定哪些属性需要作为参数——当类型T含有不需要随 HTTP 调用发送的属性时,这一选项非常有用。其核心实现依赖PropertyCache<T>:在 RestRequestExtensions.Object.cs 中调用PropertyCache<T>.GetParameters(obj, includedProperties),而PropertyCache.Populator使用System.Linq.Expressions将属性 getter 编译为Func<T, object>委托并缓存(见 PropertyCache.Populator.cs),同时根据属性类型(IFormattableIConvertibleIEnumerable等)选择不同的转换与序列化路径(CSV 拼接或数组参数)。

使用自定义参数名或格式时同样借助RequestProperty特性。示例:

class TestObject { [RequestProperty(Name = "some_data")] public string SomeData { get; set; } [RequestProperty(Format = "d")] public DateTime SomeDate { get; set; } [RequestProperty(Name = "dates", Format = "d")] public DateTime[] DatesArray { get; set; } public int Plain { get; set; } public DateTime[] PlainArray { get; set; } }

URL segment parameter:路径占位符替换

GetOrPost不同,URL segment 参数用于替换请求 URL 中的占位符:

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

请求执行时,RestSharp 会把 URL 中的任何{placeholder}与同名(不含{})参数匹配并替换为参数值,因此上面的代码最终请求 URL 为health/s2/status

从源码看,AddUrlSegment创建UrlSegmentParameter,并通过AddOrUpdateParameter添加(同名占位符可覆盖),encode默认true(见 RestRequestExtensions.Url.cs)。泛型重载AddUrlSegment<T>同样支持指定 culture 格式化值(见 RestRequestExtensions.Url.cs)。

URL segment 参数同样可以作为客户端默认参数添加:

client.AddDefaultUrlSegment("foo", "bar");

底层实现在 RestClient.Extensions.Params.cs,会为客户端所有请求的 URL 占位符填充该值。

Cookies:请求级与客户端级 Cookie

使用AddCookie方法即可向请求添加 Cookie:

request.AddCookie("foo", "bar");

两个参数的形式会把域解析推迟到执行时刻——Cookie 域从请求 URL 推断。如果需要显式指定路径和域,使用四个参数的重载:

request.AddCookie("foo", "bar", "/path", "example.com");

RestSharp 会把请求中的 Cookie 作为 Cookie 头发送,然后从响应中提取匹配的 Cookie。你可以通过RestResponse.Cookies属性(类型为CookieCollection)观察和提取响应 Cookie(见 RestResponseBase.cs)。

在请求级别存在一个CookieContainer实例。你可以把预先填充好的容器赋给request.CookieContainer,也可以让容器在执行时自动创建。四参数AddCookie重载会立即填充容器,而两参数形式先把 Cookie 存入PendingCookies列表(见 RestRequest.cs),直到请求执行时才解析。执行时,RestSharp 会从容器中取出全部 Cookie 生成 Cookie 头,而不是直接使用容器本身——因为 Cookie 容器通常配置在HttpClientHandler级别,同一客户端发起的多个请求之间会共享 Cookie,这在多数场景下是有害的。

如果你的用例确实需要在客户端实例的各请求之间共享 Cookie,可以使用客户端级别的CookieContainer,它必须通过 options 属性提供。你可以使用容器 API 向其中添加 Cookie,但响应 Cookie 不会自动加入容器;需要时可以在代码中从响应的Cookies属性取出,再手动添加到通过IRestClient.Options.CookieContainer属性访问的客户端级容器。

Request Body 请求体

RestSharp 支持多种添加请求体的方式:

  • AddJsonBody—— JSON 负载
  • AddXmlBody—— XML 负载
  • AddStringBody—— 预序列化负载

官方推荐使用AddJsonBodyAddXmlBody,而不是带BodyParameterAddParameter——前两者会设置正确的请求类型并替你完成序列化工作。

当发起POSTPUTPATCH请求并添加了GetOrPost参数时,RestSharp 默认会把它们作为 URL 编码的表单请求体发送;当请求同时有文件时,则发送multipart/form-data请求。你也可以通过把AlwaysMultipartFormData属性设为true强制 RestSharp 以multipart/form-data发送请求体(对应源码属性定义见 RestRequest.cs)。

如有需要,可以指定自定义的请求体内容类型——contentType参数在所有添加请求体的重载中均可使用。

注意:无法添加客户端级别的默认请求体参数

String body:字符串请求体

如果你有预序列化的负载(例如一段 JSON 字符串),可以用AddStringBody将其作为请求体参数添加。必须指定内容类型,以便远端端点知道如何处理请求体。例如:

const json = "{ \"data\": { \"foo\": \"bar\" } }"; request.AddStringBody(json, ContentType.Json);

AddStringBody(string, ContentType)直接创建BodyParameter(见 RestRequestExtensions.Body.cs),还有接受DataFormat的重载会由ContentType.FromDataFormat推导内容类型(见 RestRequestExtensions.Body.cs)。

JSON body:JSON 请求体

调用AddJsonBody时,RestSharp 会为你完成以下工作:

  • 指示 RestClient 在发起请求时把对象参数序列化为 JSON;
  • 将内容类型设置为application/json
  • 将请求体的内部数据类型设置为DataType.Json

示例:

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

可以通过contentType参数覆盖默认内容类型:

request.AddJsonBody(param, "text/x-json");

如果向AddJsonBody传入预序列化的字符串,它会原样发送。AddJsonBody会检测参数是否为字符串,若是则作为带 JSON 内容类型的字符串请求体添加。本质上这意味着:使用AddJsonBody时,顶层字符串不会被序列化为 JSON。要解决此问题,可以使用带forceSerialize参数的AddJsonBody重载,强制把字符串序列化为 JSON:

const string payload = @" ""requestBody"": { ""content"": { ""application/json"": { ""schema"": { ""type"": ""string"" } } } },"; request.AddJsonBody(payload, forceSerialize: true); // 字符串会被序列化 request.AddJsonBody(payload); // 字符串不会被序列化,原样发送

从源码可以看到这一分支逻辑:AddJsonBody<T>(T obj, ...)中若obj is string str则走AddStringBody(str, DataFormat.Json),否则创建JsonParameter(见 RestRequestExtensions.Body.cs);而带forceSerialize的重载在forceSerialize: true时直接创建JsonParameter(见 RestRequestExtensions.Body.cs)。

XML body:XML 请求体

调用AddXmlBody时,RestSharp 会为你完成以下工作:

  • 指示 RestClient 在发起请求时把对象参数序列化为 XML;
  • 将内容类型设置为application/xml
  • 将请求体的内部数据类型设置为DataType.Xml

源码实现在 RestRequestExtensions.Body.cs,其中AddXmlBody<T>还接受可选参数xmlNamespace用于指定 XML 命名空间。

:::warning 不要把 XML 字符串传给AddXmlBody,那样不会生效! :::

Uploading files:上传文件

使用RestRequestAddFile函数即可向请求添加文件。主函数接受FileParameter参数:

request.AddFile(fileParameter);

你可以用FileParameter.Create(接受字节数组)或FileParameter.FromFile(从磁盘加载文件)实例化文件参数(见 FileParameter.cs)。FromFile会校验文件是否存在,不存在时抛出FileNotFoundExceptionCreate的字节数组重载内部把字节写入MemoryStream再返回流。

还有多个封装了FileParameter创建的扩展函数:

// 从磁盘添加文件 AddFile(parameterName, filePath, contentType); // 添加字节数组 AddFile(parameterName, bytes, fileName, contentType); // 添加 getFile 函数返回的流 AddFile(parameterName, getFile, fileName, contentType);

这三个重载的签名与源码一一对应(见 RestRequestExtensions.File.cs):磁盘路径重载调用FileParameter.FromFile,字节与流重载调用FileParameter.Create

请记住:AddFile会设置所有必要的头,因此不要手动设置内容头。

你还可以为AddFile调用提供文件上传选项,选项如下:

  • DisableFilenameEncoding(默认false):设为true时,RestSharp 不会对Content-Disposition头中的文件名进行编码;
  • DisableFilenameStar(默认true):设为true时,RestSharp 不会向Content-Disposition头添加filename*参数。

FileParameterOptions类定义见 FileParameter.cs,两个选项默认值分别为falsetrue。选项使用示例:

var options = new FileParameterOptions { DisableFilenameEncoding = true, DisableFilenameStar = false }; request.AddFile("file", filePath, options: options);

上面代码中的选项组合通常有助于上传文件名含非 ASCII 字符的文件——DisableFilenameEncoding = true避免对文件名做百分号编码,DisableFilenameStar = false允许添加filename*参数,使服务器能正确识别带非 ASCII 字符的原始文件名。

延伸阅读

  • 请求执行与响应处理:见 usage/execute.md 与 usage/response.md
  • 客户端配置与基础用法:见 usage/client.md 与 usage/basics.md
  • 序列化与内容类型:见 advanced/serialization.md
  • 相关核心源码:RestRequest.cs、RestRequestExtensions.Body.cs、RestRequestExtensions.File.cs、PropertyCache.Populator.cs、ObjectParser.cs
  • 后端
  • API设计

【免费下载链接】RestSharp

Simple REST and HTTP API Client for .NET

项目地址:https://gitcode.com/gh_mirrors/re/RestSharp
点击查看免费下载
上一篇:AriaNg终极配置指南:3步快速搭建现代化下载管理平台
下一篇:命令行上传Zenodo大文件的终极解决方案:zenodo-upload

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询