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

如何在ASP.NET Core 7中将纯字符串以JSON格式返回?

ASP.NET Core 7全局设置字符串响应默认返回application/json

问题背景

从.NET Framework迁移到ASP.NET Core 7时,遇到响应序列化差异:返回简单字符串的端点默认Content-Type为text/plain,字符串不带引号,不符合原ASP.NET Framework中默认返回JSON格式(带引号、Content-Type为application/json)的行为。

示例控制器代码:

[ApiController]
[Route("[controller]")]
public class SanityController : ControllerBase
{
    public SanityController()
    {
    }

    [HttpGet]
    public string Get()
    {
        return "Where are the quotes?";
    }
}

Program.cs配置(已尝试的JSON序列化配置):

var builder = WebApplication.CreateBuilder(args);

// 曾尝试配置JsonOptions,效果和AddJsonOptions一致
//builder.Services.Configure<JsonOptions>(options =>
//{
//    options.SerializerOptions.IncludeFields = true;
//    options.SerializerOptions.Converters.Add(new JsonStringEnumConverter());
//    options.SerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
//    options.SerializerOptions.PropertyNameCaseInsensitive = true;
//});

builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.IncludeFields = true;
        options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
        options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
        options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
    });

app.Run();

目前问题:

  • 返回字符串的端点默认Content-Type为text/plain
  • 修改客户端Accept头为application/json时可返回JSON,但浏览器直接访问仍返回text/plain
  • 单个方法添加[Produces("application/json")]可解决,但需要全局生效的方案

解决方案

方法1:自定义字符串输出格式化器

创建自定义输出格式化器,覆盖字符串类型的序列化逻辑,强制返回带引号的JSON格式:

  1. 实现自定义格式化器类:
public class StringJsonOutputFormatter : TextOutputFormatter
{
    public StringJsonOutputFormatter()
    {
        SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/json"));
        SupportedEncodings.Add(Encoding.UTF8);
        SupportedEncodings.Add(Encoding.Unicode);
    }

    protected override bool CanWriteType(Type? type)
    {
        return type == typeof(string);
    }

    public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
    {
        var response = context.HttpContext.Response;
        var value = context.Object as string;
        var json = JsonSerializer.Serialize(value);
        await response.WriteAsync(json, selectedEncoding);
    }
}
  1. 在Program.cs中注册该格式化器(插入到格式化器列表最前面,确保优先生效):
builder.Services.AddControllers(options =>
{
    options.OutputFormatters.Insert(0, new StringJsonOutputFormatter());
})
.AddJsonOptions(options =>
{
    options.JsonSerializerOptions.IncludeFields = true;
    options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
    options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
    options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
});

方法2:全局添加Produces特性

通过全局过滤器强制所有控制器默认返回application/json类型:

builder.Services.AddControllers(options =>
{
    options.Filters.Add(new ProducesAttribute("application/json"));
})
.AddJsonOptions(options =>
{
    options.JsonSerializerOptions.IncludeFields = true;
    options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
    options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
    options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
});

方法3:使用ActionFilter拦截转换字符串响应

创建ActionFilter,拦截返回字符串的结果并转换为JSON格式:

  1. 实现ActionFilter类:
public class StringToJsonFilter : IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext context) { }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        if (context.Result is ObjectResult objectResult && objectResult.Value is string strValue)
        {
            var jsonValue = JsonSerializer.Serialize(strValue);
            context.Result = new ContentResult
            {
                Content = jsonValue,
                ContentType = "application/json",
                StatusCode = objectResult.StatusCode
            };
        }
    }
}
  1. 全局注册该Filter:
builder.Services.AddControllers(options =>
{
    options.Filters.Add<StringToJsonFilter>();
})
.AddJsonOptions(options =>
{
    options.JsonSerializerOptions.IncludeFields = true;
    options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
    options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
    options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
});

说明

  • 方法1是最贴合原ASP.NET Framework行为的方案,直接修改字符串类型的序列化规则
  • 方法2强制全局响应类型为application/json,浏览器访问时也会返回带引号的JSON字符串
  • 方法3适合需要对字符串响应做额外处理的场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 03:07:12