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

从.NET Framework WebApi迁移到.NET Core:如何按查询参数选择OutputFormatter?

.NET Core WebApi 根据查询参数选择 OutputFormatter 实现方案

在.NET Core WebApi中,原.NET Framework依赖的IContentNegotiator已被全新的内容协商机制替代,以下是适配迁移需求的具体实现方案:

1. 适配自定义 OutputFormatter

先将原ConvertResultRawFormatter改造为.NET Core标准的OutputFormatter(对应Framework中的MediaTypeFormatter):

public class ConvertResultRawFormatter : OutputFormatter
{
    public ConvertResultRawFormatter()
    {
        // 声明格式化器支持的媒体类型
        SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/plain"));
    }

    protected override bool CanWriteType(Type type)
    {
        // 定义该格式化器可处理的数据类型,按需调整逻辑
        return true;
    }

    public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context)
    {
        var response = context.HttpContext.Response;
        // 替换为你的原始格式序列化逻辑
        var rawContent = context.Object?.ToString() ?? string.Empty;
        await response.WriteAsync(rawContent);
    }
}

2. 实现查询参数驱动的内容协商

方式一:自定义内容协商策略

创建自定义策略类,读取查询参数并匹配对应的格式化器:

public class QueryParamContentNegotiationPolicy : IContentNegotiationPolicy
{
    public ContentNegotiationResult Negotiate(Type type, HttpRequest request, IList<IOutputFormatter> formatters)
    {
        // 获取查询参数(示例使用"format"作为参数名)
        var format = request.Query["format"].FirstOrDefault()?.ToLower();
        
        IOutputFormatter targetFormatter = format switch
        {
            "raw" => formatters.FirstOrDefault(f => f is ConvertResultRawFormatter),
            "json" => formatters.FirstOrDefault(f => f is SystemTextJsonOutputFormatter),
            // 可扩展更多格式规则
            _ => formatters.FirstOrDefault(f => f is SystemTextJsonOutputFormatter) // 默认返回JSON格式化器
        };

        if (targetFormatter != null)
        {
            // 返回选中的格式化器及对应媒体类型
            var mediaType = targetFormatter is ConvertResultRawFormatter ? "text/plain" : "application/json";
            return new ContentNegotiationResult(targetFormatter, MediaTypeHeaderValue.Parse(mediaType));
        }

        // 无匹配时使用默认协商逻辑
        return new DefaultContentNegotiationPolicy().Negotiate(type, request, formatters);
    }
}

在Program.cs(.NET 6+)中注册配置:

builder.Services.AddControllers(options =>
{
    // 添加自定义格式化器
    options.OutputFormatters.Add(new ConvertResultRawFormatter());
    
    // 替换默认内容协商策略
    options.ContentNegotiationPolicy = new QueryParamContentNegotiationPolicy();
    
    // 配置JSON格式化器忽略Null值(对应原JsonMediaTypeFormatter的配置)
    var jsonFormatter = options.OutputFormatters.OfType<SystemTextJsonOutputFormatter>().First();
    jsonFormatter.SerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
});

方式二:在格式化器内直接判断查询参数

如果逻辑简单,可直接在自定义格式化器中检查查询参数,决定是否启用:

public class ConvertResultRawFormatter : OutputFormatter
{
    public ConvertResultRawFormatter()
    {
        SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/plain"));
    }

    protected override bool CanWriteType(Type type)
    {
        return true;
    }

    public override bool CanWriteResult(OutputFormatterCanWriteContext context)
    {
        // 仅当查询参数指定"format=raw"时启用该格式化器
        var formatParam = context.HttpContext.Request.Query["format"].FirstOrDefault();
        return formatParam?.ToLower() == "raw" && base.CanWriteResult(context);
    }

    public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context)
    {
        var response = context.HttpContext.Response;
        var rawContent = context.Object?.ToString() ?? string.Empty;
        await response.WriteAsync(rawContent);
    }
}

注册配置简化为:

builder.Services.AddControllers(options =>
{
    options.OutputFormatters.Add(new ConvertResultRawFormatter());
    
    var jsonFormatter = options.OutputFormatters.OfType<SystemTextJsonOutputFormatter>().First();
    jsonFormatter.SerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
});

3. 测试验证

发送请求时通过查询参数指定格式:

  • 调用原始格式:GET /api/your-endpoint?format=raw
  • 调用JSON格式:GET /api/your-endpoint?format=json

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 02:35:15