You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置Refit客户端以正常支持解析BSON格式响应

问题场景

使用Refit客户端调用ASP.NET 6接口时,接口返回BSON格式数据,客户端响应的Content字段为null,无法正常获取返回值;将接口返回格式切换为JSON后,客户端可正常解析。

服务端接口定义如下:

[Produces("application/bson", Type=typeof(MyDto))]
public async Task<IActionResult> GetBinaryDataAsBson(Guid id)

服务端已实现自定义BSON输出格式化器,基于Newtonsoft的BsonDataWriter完成BSON写入,核心代码:

public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context)
{
    var response = context.HttpContext.Response;

    using (var ms = new MemoryStream())
    {
        using (var bsonWriter = new BsonDataWriter(ms) { CloseOutput = false })
        {
            var jsonSerializer = JsonSerializer.Create(_jsonSerializerSettings);
            jsonSerializer.Serialize(bsonWriter, context.Object);
            bsonWriter.Flush();
        }

        return response.Body.WriteAsync(ms.GetBuffer(), 0, (int)ms.Length);
    }
}
解决方案

Refit默认仅内置JSON、XML等通用格式的解析逻辑,无法自动识别application/bson类型的响应,需要手动添加自定义BSON解析支持,配置步骤如下:

  • 实现Refit提供的IContentSerializer接口,编写BSON反序列化逻辑
using Newtonsoft.Json;
using Newtonsoft.Json.Bson;
using Refit;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

public class BsonContentSerializer : IContentSerializer
{
    private readonly JsonSerializerSettings _jsonSerializerSettings;

    public BsonContentSerializer(JsonSerializerSettings? serializerSettings = null)
    {
        _jsonSerializerSettings = serializerSettings ?? new JsonSerializerSettings();
    }

    public async Task<T?> DeserializeAsync<T>(HttpContent content)
    {
        using var responseStream = await content.ReadAsStreamAsync();
        using var bsonReader = new BsonDataReader(responseStream);
        var serializer = JsonSerializer.Create(_jsonSerializerSettings);
        return serializer.Deserialize<T>(bsonReader);
    }

    public Task<HttpContent> SerializeAsync<T>(T item)
    {
        // 若不需要向服务端发送BSON格式请求,保留默认JSON序列化逻辑即可;如有需求可自行实现BSON请求序列化
        var jsonContent = JsonConvert.SerializeObject(item, _jsonSerializerSettings);
        return Task.FromResult<HttpContent>(new StringContent(jsonContent, Encoding.UTF8, "application/json"));
    }
}
  • 初始化Refit客户端时,传入配置了自定义BSON序列化器的RefitSettings
var refitSettings = new RefitSettings
{
    ContentSerializer = new BsonContentSerializer(/* 可传入与服务端一致的Json序列化配置,保证字段匹配 */)
};

var apiClient = RestService.For<IDataApi>("你的服务端根地址", refitSettings);
  • 在Refit对应的接口方法上添加请求头,声明客户端接受BSON格式响应,避免服务端内容协商阶段返回非预期格式
public interface IDataApi
{
    [Headers("Accept: application/bson")]
    [Get("/api/your-route/{id}")]
    Task<MyDto> GetBinaryDataAsBson(Guid id);
}

补充校验项:需确认服务端自定义的BsonMediaTypeFormatter已将application/bson加入SupportedMediaTypes集合,否则服务端不会执行BSON序列化逻辑。

内容的提问来源于stack exchange,提问作者Guitarman1024

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 03:18:34