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

配置Accept头为application/vnd.api+json遇问题及JSON带反斜杠求助

问题解决方案

问题1:设置Accept头为"application/vnd.api+json"时触发媒体类型不支持错误

可能原因

  • 目标API本身不支持application/vnd.api+json媒体类型,需先确认API文档说明。
  • ASP.NET Core项目未配置对该媒体类型的支持,导致框架无法处理对应的响应格式。
  • HttpClient的Accept头设置存在冲突,未完全清除原有头信息。

解决方案

  1. 确认目标API支持:先查阅目标API的官方文档,确认其是否接受application/vnd.api+json作为Accept头的值。如果API不支持,需改用文档指定的媒体类型。
  2. 配置ASP.NET Core支持该媒体类型:在Program.cs中添加对该媒体类型的JSON格式化支持:
builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
        // 添加自定义媒体类型映射
        options.OutputFormatters.OfType<SystemTextJsonOutputFormatter>()
            .First()
            .SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/vnd.api+json"));
    });
  1. 正确设置HttpClient的Accept头:确保清除原有Accept头后再添加新的媒体类型:
_httpClient.DefaultRequestHeaders.Accept.Clear();
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/vnd.api+json"));

问题2:返回的JSON结果带有多余反斜杠

原因

当前代码中调用await personCredentials.Content.ReadAsStringAsync()获取的是已经序列化好的JSON字符串,而Ok()方法会将这个字符串再次进行JSON序列化,导致字符串中的双引号被转义,出现多余反斜杠。

解决方案

有两种方式解决:

方式1:反序列化为对象后返回(推荐)

将API响应的JSON字符串反序列化为.NET对象,再返回对象,ASP.NET Core会自动正确序列化:

// 先定义对应的实体类,比如PersonCredential
var jsonString = await personCredentials.Content.ReadAsStringAsync();
var credentials = JsonSerializer.Deserialize<List<PersonCredential>>(jsonString);
return Ok(credentials);

注:需要根据API返回的JSON结构定义对应的实体类PersonCredential

方式2:直接返回原始JSON内容

使用Content()方法返回原始JSON字符串,并指定媒体类型,避免再次序列化:

var jsonString = await personCredentials.Content.ReadAsStringAsync();
return Content(jsonString, "application/json");

修改后的完整代码示例

[Route("api/[controller]")]
[ApiController]
[Produces("application/json", "application/vnd.api+json")] // 添加支持的媒体类型
public class ProjectController : ControllerBase // 类名遵循大驼峰命名规范
{
    private readonly IConfiguration _configuration;
    private readonly HttpClient _httpClient;

    public ProjectController(IConfiguration configuration, HttpClient httpClient)
    {
        _configuration = configuration;
        _httpClient = httpClient;
    }

    [HttpGet]
    public async Task<IActionResult> Get()
    {
        try
        {
            // 设置API密钥
            _httpClient.DefaultRequestHeaders.Authorization =
                new AuthenticationHeaderValue("Bearer", _configuration["ApiSettings:ApiKey"]);

            var content = new StringContent("", Encoding.UTF8, "application/json");
            var authResponse = await _httpClient.PostAsync("https://www.example.com/auth", content);

            if (!authResponse.IsSuccessStatusCode)
            {
                return BadRequest("认证失败");
            }

            // 解析认证令牌(注意:如果返回的是JSON对象,建议反序列化为对象提取token,避免直接用字符串)
            var authToken = await authResponse.Content.ReadAsStringAsync();
            // 示例:如果authResponse返回的是{"token":"xxx"},应该反序列化后取token字段
            // var authResult = JsonSerializer.Deserialize<AuthResult>(authToken);
            // var token = authResult.Token;

            // 设置请求头
            _httpClient.DefaultRequestHeaders.Accept.Clear();
            _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/vnd.api+json"));
            _httpClient.DefaultRequestHeaders.Authorization =
                new AuthenticationHeaderValue("Bearer", authToken);

            var url = "https://www.example.com/api/credential/";
            var personCredentials = await _httpClient.GetAsync(url);
            personCredentials.EnsureSuccessStatusCode(); // 确保请求成功,否则抛出异常

            // 方式1:反序列化为对象返回(推荐)
            var jsonString = await personCredentials.Content.ReadAsStringAsync();
            var credentials = JsonSerializer.Deserialize<List<PersonCredential>>(jsonString);
            return Ok(credentials);

            // 方式2:直接返回原始JSON
            // var jsonString = await personCredentials.Content.ReadAsStringAsync();
            // return Content(jsonString, "application/json");
        }
        catch (HttpRequestException ex)
        {
            string errorMessage = $"API调用错误: {ex.Message}";
            return StatusCode((int)ex.StatusCode, errorMessage);
        }
    }
}

// 示例实体类,根据实际API返回结构调整
public class PersonCredential
{
    public int Id { get; set; }
    public string Name { get; set; }
    // 其他属性...
}

// 认证响应实体类(如果需要)
public class AuthResult
{
    public string Token { get; set; }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 19:23:21