拓冰建站拓冰建站
首页 / 资讯中心 / 正文

RestSharp 序列化完全指南:从 JSON/XML 到自定义序列化器

后端API设计【免费下载链接】RestSharpSimple REST and HTTP API Client for .NET项目地址https://gitcode.com/gh_mirrors/re/RestSharp点击查看免费下载RestSharp 相比裸HttpClient最突出的优势之一就是内建了完整的请求/响应序列化能力发送请求时可以把复杂对象作为请求体自动序列化接收响应时又能把内容反序列化为指定的 .NET 类型。默认开箱即用地支持 JSON 与 XML还额外提供 CSV 序列化器以及完整的自定义扩展点IRestSerializer接口。读完本文你将掌握如何通过configureSerialization配置序列化器、如何选用并调优 System.Text.Json / XML / NewtonsoftJson / CsvHelper 四种方案、如何实现并注册自己的序列化器以及反序列化失败时的行为与应对。本文以 v111 版序列化文档 为骨架并结合 src/RestSharp/Serializers 下的真实源码展开讲解。为什么需要序列化支持选 RestSharp 而非裸HttpClient的常见理由正是它内置的序列化支持。当你需要调用某个 API 端点时RestSharp 允许把复杂对象直接作为请求体body加入请求并在发起调用时自动完成序列化反过来响应内容也会被自动反序列化成你指定的 .NET 类型。默认支持 JSON 与 XML的序列化和反序列化除此之外还可用CSV 序列化器或者编写自己的序列化器与System.Net.Http.Json包其中只包含针对GET/POST的 JSON 扩展方法不同RestSharp 对所有 HTTP 方法都支持 JSON 响应而不只是GET。从实现上看序列化发生在客户端调度的核心链路里RestSerializers.DeserializeT在拿到原始RestResponse后调用DeserializeContentT完成反序列化并依据 RestClientOptions 中的错误处理选项决定是吞掉异常还是抛出详见下文反序列化失败怎么办一节。序列化配置总览所有序列化相关的配置都发生在创建RestClient时的configureSerialization构造函数参数里这个参数的类型是 SerializerConfig。用 configureSerialization 注册自定义序列化器var client new RestClient( options, configureSerialization: s s.UseSerializer(() new CustomSerializer()) );SerializerConfig.UseSerializer接收一个返回IRestSerializer实例的工厂函数FuncIRestSerializerRestSharp 会把该实例按它的DataFormat登记到内部字典中见 SerializerConfig.cs。这意味着序列化器是按数据格式注册的同一个客户端可以为不同格式挂不同实现。IRestSerializer 接口与 Accept 头所有 RestSharp 序列化器都实现 IRestSerializer 接口public interface IRestSerializer { ISerializer Serializer { get; } IDeserializer Deserializer { get; } string[] AcceptedContentTypes { get; } SupportsContentType SupportsContentType { get; } DataFormat DataFormat { get; } string? Serialize(Parameter parameter); }其中AcceptedContentTypes属性必须返回该序列化器支持的内容类型集合。当客户端配置好若干序列化器后RestSharp 会收集所有AcceptedContentTypes并据此填充请求的Accept头——这正是RestSerializers.GetAcceptedContentTypes()的实现见 RestSerializers.cs所以你通常不需要手动设置Accept头。以 JSON 为例ContentType.JsonAccept定义了四个可接受的媒体类型见 ContentType.cspublic static readonly string[] JsonAccept [Json, text/json, text/x-json, text/javascript];即application/json、text/json、text/x-json、text/javascript。请求体内容类型的自动设置发起调用时RestSharp 会根据请求体body的类型自动设置请求的Content-Type。例如使用AddJsonBody时内容类型会被设为application/json因此一般情况下你无需手动设置Content-Type头。如果确实需要为 JSON 调用指定自定义内容类型可以使用AddJsonBody的可选contentType参数request.AddJsonBody(data, text/json);常用配置辅助方法SerializerConfigExtensions 提供了一组便捷方法用于裁剪序列化器集合UseJson()—— 仅使用 JSON移除 XML 注册UseXml()—— 仅使用 XML移除 JSON 注册UseOnlySerializer(factory)—— 清空现有注册仅保留传入的自定义序列化器UseDefaultSerializers()—— 恢复默认的SystemTextJsonSerializerXmlRestSerializer组合。JSON默认的 System.Text.Json 序列化器默认 JSON 序列化器是SystemTextJsonSerializer实现见 SystemTextJsonSerializer.cs。System.Text.Json自 .NET 6 起成为 .NET 运行时的一部分对于更早的框架版本它会作为依赖被引入。默认使用 Web 配置默认情况下RestSharp 使用JsonSerializerDefaults.Web配置创建JsonSerializerOptions这会让属性名采用 camelCase小驼峰绑定、大小写不敏感等 Web 场景约定public SystemTextJsonSerializer() _options new(JsonSerializerDefaults.Web);自定义 JsonSerializerOptions如果你需要不同的行为例如自定义命名策略、转换器、缩进等可以传入自己的JsonSerializerOptions实例var client new RestClient( options, configureSerialization: s s.UseSystemTextJson(new JsonSerializerOptions { /* ... */ }) );对应的扩展方法定义在 RestClientExtensions.csUseSystemTextJson()使用默认 Web 配置UseSystemTextJson(JsonSerializerOptions options)使用自定义配置两者最终都通过UseSerializer注册。底层实现要点从源码看SystemTextJsonSerializer同时实现了IRestSerializer、ISerializer与IDeserializer三个接口Serialize(object)走JsonSerializer.Serialize(obj, _options)DeserializeT(RestResponse)走JsonSerializer.DeserializeT(response.Content!, _options)ContentType默认为ContentType.Jsonapplication/jsonSupportsContentType判定规则是内容类型字符串以json结尾忽略大小写。XML默认与可选的两套实现默认DotNetXmlSerializer默认的 XML 序列化器是DotNetXmlSerializer基于 .NET 的System.Xml.Serialization库实现见 DotNetXmlSerializer.cs与DotNetXmlDeserializer一起通过XmlRestSerializer组合成IRestSerializer见 XmlRestSerializer.cs。public XmlRestSerializer() : this(new DotNetXmlSerializer(), new DotNetXmlDeserializer()) { }从源码看DotNetXmlSerializer有几点值得注意的实现细节默认使用ContentType.Xml与 UTF-8 编码支持通过构造参数或属性设置 XML命名空间Namespace与根元素名RootElement内部用Dictionary(Type, string?), XmlSerializer对XmlSerializer实例做了缓存并配合ReaderWriterLockSlim保证线程安全见 DotNetXmlSerializer.cs——因为创建XmlSerializer开销较大缓存能显著提升高频调用的性能。可选独立的 RestSharp.Serializers.Xml 包在早期版本的 RestSharp 中默认 XML 序列化器是自研的自定义 XML 序列化器。为了缩小核心库的体积现在该序列化器被拆分到了独立的 NuGet 包RestSharp.Serializers.Xml中对应仓库目录 src/RestSharp.Serializers.Xml。如果确实需要可以安装该包并把它加回客户端var client new RestClient( options, configureSerialization: s s.UseXmlSerializer() );从 XmlSerializerClientExtensions.cs 的实现看UseXmlSerializer签名如下public static SerializerConfig UseXmlSerializer( this SerializerConfig config, string? xmlNamespace null, string? rootElement null, bool useAttributeDeserializer false )三个可选参数的含义xmlNamespace—— 序列化时使用的自定义 XML 命名空间rootElement—— 序列化时使用的自定义根元素名称useAttributeDeserializer—— 置为true时使用XmlAttributeDeserializer按 XML 特性反序列化而非默认的XmlDeserializer按子元素反序列化。这也就是文档中提到的三个可选参数自定义命名空间、自定义根元素、是否使用SerializeAs/DeserializeAs特性的落地形态。NewtonsoftJsonaka Json.NetNewtonsoftJsonJson.Net是 .NET 生态中最流行的 JSON 序列化库几乎能覆盖所有场景且高度可配置。不过这种灵活性也带来了性能开销——如果你更看重速度请保留默认的 System.Text.Json 序列化器。安装与启用RestSharp 通过独立包RestSharp.Serializers.NewtonsoftJson支持 Json.Net对应仓库目录 src/RestSharp.Serializers.NewtonsoftJson。使用该包提供的扩展方法即可完成配置var client new RestClient( options, configureSerialization: s s.UseNewtonsoftJson() );:::warning 请注意NuGet 上名为RestSharp.Newtonsoft.Json的包并非 RestSharp 官方提供在 NuGet 上已被标记为 obsolete原作者也已停止维护。请使用官方包RestSharp.Serializers.NewtonsoftJson。 :::默认配置项JsonNetSerializer默认使用一组设置见 JsonNetSerializer.cspublic static readonly JsonSerializerSettings DefaultSettings new() { ContractResolver new CamelCasePropertyNamesContractResolver(), DefaultValueHandling DefaultValueHandling.Include, TypeNameHandling TypeNameHandling.None, NullValueHandling NullValueHandling.Ignore, Formatting Formatting.None, ConstructorHandling ConstructorHandling.AllowNonPublicDefaultConstructor };各项含义设置项含义ContractResolver CamelCasePropertyNamesContractResolver()属性名序列化为 camelCase小驼峰DefaultValueHandling Include序列化时包含默认值属性TypeNameHandling None不输出 .NET 类型名避免类型注入风险NullValueHandling Ignore序列化时忽略 null 值的属性Formatting None不缩进输出紧凑 JSONConstructorHandling AllowNonPublicDefaultConstructor允许使用非公开的默认构造函数如果你需要不同的设置可以把自己的JsonSerializerSettings实例作为参数传给扩展方法var client new RestClient( options, configureSerialization: s s.UseNewtonsoftJson(myCustomSettings) );底层上JsonNetSerializer用JsonSerializer.Create(settings)创建实例序列化走JsonTextWriter配合WriterBuffer复用缓冲区见 WriterBuffer.cs反序列化走JsonTextReader其SupportsContentType判定为内容类型字符串包含json。CSV基于 CsvHelper 的序列化器独立的RestSharp.Serializers.CsvHelper包为 RestSharp 提供了 CSV 序列化支持底层基于CsvHelper库实现见 CsvHelperSerializer.cs。启用方式使用该包提供的扩展方法var client new RestClient( options, configureSerialization: s s.UseCsvHelper() );也可以传入自定义的CsvConfiguration实例var client new RestClient( options, configureSerialization: s s.UseCsvHelper( new CsvConfiguration(CultureInfo.InvariantCulture) { /* ... */ } ) );默认构造使用CultureInfo.InvariantCulture。实现行为从源码看CsvHelperSerializer的DataFormat返回DataFormat.NoneAcceptedContentTypes为[ContentType.Csv, application/x-download]即text/csv与application/x-download。其序列化/反序列化逻辑序列化传入IEnumerable时用csvWriter.WriteRecords(records)输出整组记录传入单个对象时先写表头WriteHeader再写单条记录反序列化目标类型T若实现了IEnumerableT则要求具备公开无参构造函数与公开的Add(T)方法逐条读取记录并填充非集合类型则读取单条记录返回若T不满足上述约束会抛出InvalidOperationException反序列化过程中的异常统一包装为DeserializationException。自定义序列化器实现 IRestSerializer如果要同时支持序列化与反序列化你需要实现IRestSerializer接口。下面是一个使用System.Text.Json的自定义序列化器示例与内置SystemTextJsonSerializer的实现思路一致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? DeserializeT(RestResponse response) JsonSerializer.DeserializeT(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); }注册方式var client new RestClient( options, configureSerialization: s s.UseSerializer(() new SimpleJsonSerializer()) );各成员的作用Serializer/Deserializer分别暴露ISerializer见 ISerializer.cs含ContentType属性与Serialize(object)与IDeserializer见 IDeserializer.cs含DeserializeT(RestResponse)。示例中直接让同一个类实现全部三个接口并 this返回自身DataFormat声明本序列化器对应的数据格式DataFormat.Json/DataFormat.Xml等UseSerializer会按此格式登记AcceptedContentTypes返回支持的内容类型集合用于填充Accept头SupportsContentType一个委托delegate bool SupportsContentType(ContentType)见 ContentType.cs用于根据响应头Content-Type判断该序列化器是否能够反序列化本次响应。例如上面的实现以内容类型以 json 结尾忽略大小写为判定条件ContentType在发起请求时使用让服务器知道如何处理请求负载payload从而正确设置Content-Type头。反序列化器选择的底层逻辑RestSerializers.GetContentDeserializer见 RestSerializers.cs展示了 RestSharp 如何从多个注册的序列化器中挑选反序列化器若响应有Content-Type依次遍历已注册序列化器用各自的SupportsContentType匹配若响应没有Content-Type则依据请求的RequestFormat直接取对应格式的序列化器匹配失败时RestSharp 会根据响应内容的首字符做启发式探测——以开头按 XML、以{或[开头按 JSON再重新匹配一次。这也解释了为什么SupportsContentType的匹配规则要写得足够宽泛例如 JSON 用EndsWith(json)而非精确等于application/json真实世界的服务器返回的媒体类型五花八门精确匹配很容易漏判。反序列化失败怎么办:::tip RestSharp 的默认行为是吞掉反序列化错误并把Response.Data置为null。完整的行为说明与配置项见 Error Handling 文档。 :::如果你希望反序列化失败时得到明确反馈可以配置RestClientOptions上的相关属性FailOnDeserializationError/ThrowOnDeserializationError/ThrowOnAnyError它们作用于使用该客户端实例发起的所有请求。从RestSerializers.Deserialize的实现可以印证这一点反序列化抛出的异常会被捕获随后依据选项决定——ThrowOnAnyError时重新抛出FailOnDeserializationError或ThrowOnDeserializationError时把ResponseStatus置为ErrorThrowOnDeserializationError时还会包装成DeserializationException抛出否则仅把异常记录到响应的异常集合中。:::warning 请注意反序列化失败处理只有在序列化器本身抛异常时才生效。许多序列化器默认不抛异常而是返回null此时 RestSharp 无法得知null是因为反序列化失败还是内容本身为 null因而不会触发失败逻辑。请查阅所用序列化器的文档确认它是否可配置为在反序列化出错时抛出异常。 :::各序列化器速查序列化器来源启用方式默认行为要点System.Text.Json内置src/RestSharp/Serializers/Json默认s.UseSystemTextJson()JsonSerializerDefaults.WebcamelCase、大小写不敏感XmlDotNet内置src/RestSharp/Serializers/Xml默认s.UseDotNetXmlSerializer()System.Xml.Serialization支持命名空间/根元素/编码内部缓存XmlSerializerXmlRestSharp 自研独立包RestSharp.Serializers.Xmlsrc/RestSharp.Serializers.Xmls.UseXmlSerializer(ns, root, useAttributeDeserializer)支持命名空间、根元素、SerializeAs/DeserializeAs特性NewtonsoftJson独立包RestSharp.Serializers.NewtonsoftJsonsrc/RestSharp.Serializers.NewtonsoftJsons.UseNewtonsoftJson(settings?)camelCase、忽略 null、非公开构造函数可用功能全但性能低于默认CSVCsvHelper独立包RestSharp.Serializers.CsvHelpersrc/RestSharp.Serializers.CsvHelpers.UseCsvHelper(configuration?)CultureInfo.InvariantCulture集合类型需IEnumerableT 无参构造 Add(T)自定义自己实现IRestSerializers.UseSerializer(() new MySerializer())见上文接口各成员说明小结RestSharp 的序列化体系围绕IRestSerializer接口与SerializerConfig配置入口展开默认的 JSONSystem.Text.Json与 XMLDotNet实现开箱即用Accept头与Content-Type头由框架自动管理需要更丰富的 JSON 功能时可切换到RestSharp.Serializers.NewtonsoftJson需要 CSV 时使用RestSharp.Serializers.CsvHelper历史的自研 XML 序列化器则通过RestSharp.Serializers.Xml包按需恢复。所有序列化器的选择、排序与响应反序列化决策最终都汇聚在 RestSerializers.cs 中理解它的匹配逻辑SupportsContentType 内容首字符启发式探测能帮助你写出匹配更准确、行为更可预期的自定义序列化器。赞分享后端API设计【免费下载链接】RestSharpSimple REST and HTTP API Client for .NET项目地址https://gitcode.com/gh_mirrors/re/RestSharp点击查看免费下载相关推荐RestSharp 序列化指南从 JSON/XML 默认序列化到自定义序列化器.NETRestSharp 序列化指南从 JSON/XML 默认序列化到自定义序列化器.NET RestSharp 作为 .NET 生态中最常用的 REST/HT后端API设计RestSharp 序列化完全指南内置 JSON/XML、NewtonsoftJson、CSV 与自定义序列化器RestSharp 序列化完全指南内置 JSON/XML、NewtonsoftJson、CSV 与自定义序列化器 RestSharp 相比裸用 HttpCli后端API设计Label Studio TextArea 标签完全指南从转录标注到 OCR 区域文本的实战配置Label Studio TextArea 标签完全指南从转录标注到 OCR 区域文本的实战配置 Label Studio 的 TextArea 标签tag后端API设计上一篇ToastFish使用障碍速解新手必备的3大问题攻克指南下一篇TanStack Query Svelte v6 迁移指南从 Stores 到 Runes 的完整升级实践创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门