.NET Framework 4.7 Web API用Refit传超24个Guid时参数为Null
解决Refit调用.NET Framework Web API时大数组参数为null的问题
问题场景
我们维护一个基于.NET Framework 4.7的遗留Web API,其中有个接口接收ICollection<Guid>类型参数:
[HttpPost("customer/process")] public async Task<IHttpActionResult> ProcessCustomers([FromBody] ICollection<Guid> customerIds, CancellationToken cancellationToken) { // 当Guid数量超过24时,customerIds为null }
用Refit客户端发起请求,接口定义如下:
public interface IRefitApiClient { [HttpPost("/api/xyz/customer/process")] [Headers("content-type: application/json")] public async Task<int> ProcessCustomers([Body] IEnumerable<Guid> customerIds, CancellationToken token); }
发现当Guid数量≤24时接口正常工作,超过24个Guid后服务端接收的参数直接为null。调整过web.config里的maxJsonLength、maxRequestLength等请求限制参数没用,本地用Postman传递5000个Guid都能成功,生产环境部署在IIS上。后来改成手动把Guid列表序列化为字符串传递(客户端参数改为string),服务端能自动反序列化为列表,之前传递DateTime时也遇到过类似问题,推测是Refit的配置问题。
根本原因
Refit针对.NET Framework的默认序列化配置,在处理超过一定长度的集合时,序列化后的格式和Web API默认的Json.NET解析规则不匹配,导致服务端模型绑定失败,参数变为null。而手动序列化字符串时,服务端的模型绑定可以正确处理,说明问题出在Refit的序列化环节。
解决方案:统一Refit和Web API的序列化配置
1. 定义匹配Web API的Json序列化设置
创建和.NET Framework Web API默认规则一致的JsonSerializerSettings,同时解决之前DateTime的兼容问题:
var jsonSerializerSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver(), DateTimeZoneHandling = DateTimeZoneHandling.Utc, MaxDepth = 64, // 提升深度限制,适配大集合序列化 Formatting = Formatting.None };
2. 初始化Refit客户端时指定该配置
在创建Refit客户端实例时,传入自定义的序列化设置:
var apiClient = RestService.For<IRefitApiClient>( new HttpClient { BaseAddress = new Uri("https://your-production-api-url/") }, new RefitSettings { ContentSerializer = new JsonContentSerializer(jsonSerializerSettings) } );
3. 对齐客户端和服务端的参数类型
把客户端接口的参数类型从IEnumerable<Guid>改成和服务端一致的ICollection<Guid>,减少序列化时的类型转换差异:
public interface IRefitApiClient { [HttpPost("/api/xyz/customer/process")] [Headers("content-type: application/json")] Task<int> ProcessCustomers([Body] ICollection<Guid> customerIds, CancellationToken token); }
额外说明
- 为什么web.config调整无效:问题不是请求大小限制,而是序列化格式不匹配导致模型绑定失败,和请求长度无关
- Postman正常的原因:Postman的Json序列化格式完全符合Web API的期望,没有Refit默认配置的隐藏行为
- 之前的DateTime问题:同样是因为Refit默认的DateTime序列化规则和Web API不一致,统一配置后就能解决
内容的提问来源于stack exchange,提问作者Stack Undefined
相关产品推荐
相关产品推荐

