如何在ServiceStack中为application/json支持Range请求?
ServiceStack 让application/json支持HTTP部分内容功能的方法
ServiceStack 默认仅对官方文档指定的5种媒体类型自动启用HTTP部分内容(Range请求)支持,application/json不在这个默认列表里,所以直接添加Range头不会生效,需要手动添加对应的处理逻辑。
实现步骤:
- 自定义JSON部分内容处理器
实现IHttpPartialWriter接口,处理application/json类型的Range请求。示例如下:
public class JsonHttpPartialWriter : IHttpPartialWriter { public void WritePartial(IRequest req, IResponse res, object dto, string contentType) { // 将DTO序列化为JSON字符串 var json = HostContext.AppHost.ContentTypeFilters.SerializeToString(contentType, dto); var bytes = Encoding.UTF8.GetBytes(json); // 解析Range头,获取请求的字节范围 var range = req.GetHeader(HttpHeaders.Range); if (HttpRangeUtils.TryParseRange(range, bytes.Length, out var ranges)) { // 处理单范围请求(多范围需返回multipart/byteranges,此处做简化处理) var r = ranges[0]; var start = r.From ?? 0; var end = r.To ?? bytes.Length - 1; var length = end - start + 1; // 设置响应头 res.StatusCode = (int)HttpStatusCode.PartialContent; res.AddHeader(HttpHeaders.ContentRange, $"bytes {start}-{end}/{bytes.Length}"); res.ContentLength = length; // 返回指定字节范围的内容 res.OutputStream.Write(bytes, (int)start, (int)length); } else { // 无法解析Range头时返回完整内容 res.ContentType = contentType; res.Write(json); } } }
- 注册自定义处理器
在AppHost的Configure方法中,将自定义处理器添加到HTTP部分内容功能的处理器列表:
public override void Configure(Container container) { // 启用HTTP部分内容功能并注册JSON处理器 Plugins.Add(new HttpPartialContentFeature { PartialWriters = { ["application/json"] = new JsonHttpPartialWriter() } }); }
注意事项:
- 字节级的Range返回会生成不完整的JSON字符串,客户端解析时大概率出错。如果需要语义上的部分JSON数据返回,建议在服务接口中添加
Fields、Limit这类参数,主动返回指定部分数据,而非依赖HTTP Range头。 - 如果需要支持多范围请求(Range头指定多个片段),需要修改处理器返回
multipart/byteranges格式的响应,实现逻辑会更复杂。
内容的提问来源于stack exchange,提问作者danrockcoll
相关产品推荐
相关产品推荐

