RestSharp 序列化
选择 RestSharp 而不是简单的 HttpClient
的一个常见原因是它内置的丰富序列化支持。RestSharp 允许在调用 API 端点时将复杂对象作为请求体添加,并将响应解序列化到给定的 .NET 类型。RestSharp 默认支持 JSON 和 XML 的序列化和反序列化。此外,您还可以使用 CSV 序列化器或自定义实现。
与包含使用 JSON 进行 GET
或 POST
请求的 HttpClient
扩展的 System.Net.Http.Json
包不同,RestSharp 支持所有 HTTP 方法的 JSON 响应,而不仅仅限于 GET
。
配置
提示:
RestSharp 的默认行为是吞下反序列化错误,并将响应的
Data
属性设置为null
。有关更多信息,请参阅 错误处理。
您可以使用 configureSerialization
构造函数参数告诉 RestSharp 使用自定义序列化器:
var client = new RestClient(
options,
configureSerialization: s => s.UseSerializer(() => new CustomSerializer());
);
所有 RestSharp 序列化器都实现了 IRestSerializer
接口。接口要求实现 AcceptedContentTypes
属性,该属性必须返回序列化器支持的媒体类型集合。当配置使用特定序列化器时,RestSharp 将相应地填充 Accept
头部,因此无需手动设置。
发出请求时,RestSharp 根据请求体类型设置请求内容类型。例如,当使用 AddJsonBody
时,内容类型设置为 application/json
。通常情况下,您无需手动设置 Content-Type
头部。如果您需要为 JSON 调用设置自定义内容类型,可以使用 AddJsonBody
方法的可选 contentType
参数,例如:
request.AddJsonBody(data, "text/json");
JSON
默认 JSON 序列化器使用 System.Text.Json
,这是从 .NET 6 开始的 .NET 部分。对于更早版本,它作为依赖项添加。还提供了几个额外的序列化器包。
默认情况下,RestSharp 将使用 JsonSerializerDefaults.Web
配置。如有必要,您可以指定自己的选项:
var client = new RestClient(
options,
configureSerialization: s => s.UseSystemTextJson(new JsonSerializerOptions {...})
);
XML
默认 XML 序列化器是 DotNetXmlSerializer
,它使用 .NET 的 System.Xml.Serialization
库。
在 RestSharp 的早期版本中,默认的 XML 序列化器是一个自定义的 RestSharp XML 序列化器。为了减小库大小,现在这个序列化器作为一个单独的包 RestSharp.Serializers.Xml
提供。
如果需要,您可以安装该包并将其添加到客户端:
var client = new RestClient(
options,
configureSerialization: s => s.UseXmlSerializer()
);
如以前一样,您可以为自定义命名空间、自定义根元素以及是否使用 SerializeAs
和 DeserializeAs
注解提供三个可选参数。
NewtonsoftJson(即 Json.Net)
NewtonsoftJson
包是 .NET 中最受欢迎的 JSON 序列化器。它可以处理所有可能的情况并且非常可配置。这种灵活性伴随着性能的损失。如果需要速度,请保持默认的 JSON 序列化器。
RestSharp 通过单独的包 RestSharp.Serializers.NewtonsoftJson
支持 Json.Net 序列化器。
警告
请注意,RestSharp.Newtonsoft.Json
包在 NuGet 上被标记为过时,且不再受其创建者支持。
使用包提供的扩展方法来配置客户端:
var client = new RestClient(
options,
configureSerialization: s => s.UseNewtonsoftJson()
);
序列化器默认配置了一些选项:
JsonSerializerSettings DefaultSettings = new JsonSerializerSettings {
ContractResolver = new CamelCasePropertyNamesContractResolver(),
DefaultValueHandling = DefaultValueHandling.Include,
TypeNameHandling = TypeNameHandling.None,
NullValueHandling = NullValueHandling.Ignore,
Formatting = Formatting.None,
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
};
如果需要使用不同的设置,可以在扩展方法中提供 JsonSerializerSettings
实例作为参数。
CSV
RestSharp.Serializers.CsvHelper
包提供了一个 RestSharp 的 CSV 序列化器。它基于 CsvHelper
库。
使用包提供的扩展方法来配置客户端:
var client = new RestClient(
options,
configureSerialization: s => s.UseCsvHelper()
);
您也可以将 CsvConfiguration
实例作为扩展方法的参数参数传递。
var client = new RestClient(
options,
configureSerialization: s => s.UseCsvHelper(
new CsvConfiguration(CultureInfo.InvariantCulture) {...}
)
);
自定义
您还可以实现自定义序列化器。为了支持序列化和反序列化,必须实现 IRestSerializer
接口。
以下是一个使用 System.Text.Json
的自定义序列化器的示例:
public class SimpleJsonSerializer : IRestSerializer {
public string? Serialize(object? obj) => obj == null ? null : JsonSerializer.Serialize(obj);
public string? Serialize(Parameter bodyParameter) => Serialize(bodyParameter.Value);
public T? Deserialize<T>(RestResponse response) => JsonSerializer.Deserialize<T>(response.Content!);
public ContentType ContentType { get; set; } = ContentType.Json;
public ISerializer Serializer => this;
public IDeserializer Deserializer => this;
public DataFormat DataFormat => DataFormat.Json;
public string[] AcceptedContentTypes => ContentType.JsonAccept;
public SupportsContentType SupportsContentType
=> contentType => contentType.Value.EndsWith("json", StringComparison.InvariantCultureIgnoreCase);
}
SupportedContentTypes
函数将用于根据响应头的 Content-Type
检查序列化器是否能够基于响应内容类型进行反序列化。
ContentType
属性将在发出请求时使用,以便服务器知道如何处理负载。