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

C# Web API提交JSON配置字符串报415/400错误该如何解决?

问题根源

你遇到的两次报错本质都是ASP.NET Core的[FromBody]参数绑定规则和你传参格式不匹配导致的:

  1. 415错误:默认情况下[FromBody]只会处理application/json类型的请求,你传text/plain没有对应的输入格式化器处理,就会返回不支持的媒体类型。
  2. 改传application/json后的400错误:[FromBody]绑定string类型参数时,要求请求体是被双引号包裹的JSON字符串字面量,而你直接传了裸的JSON配置内容,JSON格式化器无法解析为string类型,就返回400错误。

可选解决方案

方案1:最省心,改服务端直接读原始请求体(推荐)

你的需求是直接存储客户端传过来的原始配置字符串,不需要做模型绑定,完全可以跳过[FromBody]的绑定逻辑,直接读取请求体的原始内容:

[HttpPost("{app}/set")] // POST /api/settings/{app}/set
public async Task<bool> Set(string app)
{
    _logger.LogInformation($"recieved request on settings/{app}/set, id: {_requestId}");
    try
    {
        using var reader = new StreamReader(Request.Body, Encoding.UTF8);
        string content = await reader.ReadToEndAsync();
        System.IO.File.WriteAllText(GetAppSettingsPath(app), content, Encoding.UTF8);
        _logger.LogInformation($"Completed request for requestId: {_requestId}");
        return true;
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, $"Error on requestId, {_requestId}");
        return false;
    }
}

改完之后客户端可以直接传原始配置内容,Content-Type设为text/plain即可,不需要做任何转义,不会再有格式错误。


方案2:保留现有接口代码,调整客户端传参

如果你不想改服务端接口,可以把客户端要传的配置字符串整体转义为JSON字符串字面量,Content-Type保持为application/json:
比如你原来要传的配置内容是{"ConnectionString":"xxx"},实际传的时候要发送成"{\"ConnectionString\":\"xxx\"}",也就是给整个字符串外层加双引号,内部的双引号转义。
另外你之前用HttpClient手动加Content-Type的写法不对,Content-Type属于内容头,应该直接在StringContent构造时指定,不需要手动加请求头:

// 正确的HttpClient写法
var httpRequest = new HttpRequestMessage 
{ 
    Method = HttpMethod.Post, 
    RequestUri = new Uri(_baseUri, string.Concat("api/settings/", app, "/set")), 
    // 第三个参数直接指定媒体类型即可
    Content = new StringContent(JsonSerializer.Serialize(content), Encoding.UTF8, "application/json") 
};

这里用JsonSerializer.Serialize(content)就能自动把你的原始配置字符串转成符合要求的JSON字符串字面量。


方案3:添加纯文本格式化器,适配text/plain请求

如果你既想保留[FromBody] string content的接口写法,又不想转义传参,可以在服务端注册MVC的时候添加官方自带的纯文本输入格式化器:

// Program.cs中注册控制器的部分修改为
builder.Services.AddControllers(options =>
{
    options.InputFormatters.Add(new Microsoft.AspNetCore.Mvc.Formatters.StringInputFormatter());
});

注册完成后客户端就可以直接传Content-Type: text/plain的原始配置内容,不需要转义,接口代码完全不用改。


请求头选用说明
  • 如果你是直接传原始的文本内容(包括JSON格式的配置字符串),选text/plain最符合语义,不需要做额外的序列化转义。
  • 如果你是在传标准的JSON结构对象,才需要用application/json。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 00:54:04