项目

RestSharp 序列化

选择 RestSharp 而不是简单的 HttpClient 的一个常见原因是它内置的丰富序列化支持。RestSharp 允许在调用 API 端点时将复杂对象作为请求体添加,并将响应解序列化到给定的 .NET 类型。RestSharp 默认支持 JSON 和 XML 的序列化和反序列化。此外,您还可以使用 CSV 序列化器或自定义实现。

与包含使用 JSON 进行 GETPOST 请求的 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()
);

如以前一样,您可以为自定义命名空间、自定义根元素以及是否使用 SerializeAsDeserializeAs 注解提供三个可选参数。

NewtonsoftJson(即 Json.Net)

NewtonsoftJson 包是 .NET 中最受欢迎的 JSON 序列化器。它可以处理所有可能的情况并且非常可配置。这种灵活性伴随着性能的损失。如果需要速度,请保持默认的 JSON 序列化器。

RestSharp 通过单独的包 RestSharp.Serializers.NewtonsoftJson 支持 Json.Net 序列化器。

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

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 属性将在发出请求时使用,以便服务器知道如何处理负载。

在本文档中