【问题标题】:ASP.NET Core 3.1 Web Api HttpPost Action parameter can't receive axios application/json HttpPost passing dataASP.NET Core 3.1 Web Api HttpPost Action 参数无法接收 axios application/json HttpPost 传递数据
【发布时间】:2021-08-27 01:36:30
【问题描述】:

我以前使用Controller而不是ApiController,今天我尝试使用ApiController,发现下面的问题。

ASP.NET Core Web Api HttpPost Action 参数无法接收 axios application/json post 传递数据

asp.net核心api代码

[ApiController]
[Route("[controller]")]
public class TestController : ControllerBase
{
    [HttpPost]
    public async Task<IActionResult> Post(string json)
    {
        return this.Ok();
    }
}

前端

var json = '{"json_data":"{\"value\":\"hello world\"}';
axios.post('Test', {"json": json})
    .then(function (response) {
        console.log(response);
    })
    .catch(function (error) {
        console.log(error);
    });   

实际要求

Accept:application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Content-Type: application/json;charset=UTF-8
Request Payload : 
{"json_data":"{\"value\":\"hello world\"}

实际动作json参数数据为null 预期接收数据:{"json_data":"{\"value\":\"hello world\"}


更新

我尝试了下面的代码,我得到 rawValue value = {"json_data":"{\"value\":\"hello world\"} 但 json value = null

[HttpPost]
public async Task<IActionResult> Post(string json)
{
    using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
    {
        string rawValue = await reader.ReadToEndAsync();
    }
}

【问题讨论】:

    标签: c# .net asp.net-core asp.net-web-api asp.net-core-3.1


    【解决方案1】:

    公共异步任务发布(字符串 json)

    如果您想使用数据从前端发出 HTTP 请求并将其正确绑定到 string-type ACTION 参数,您可以尝试实现并使用自定义纯文本输入格式化程序。

    public class TextPlainInputFormatter : TextInputFormatter
    {
        public TextPlainInputFormatter()
        {
            SupportedMediaTypes.Add("text/plain");
            SupportedEncodings.Add(UTF8EncodingWithoutBOM);
            SupportedEncodings.Add(UTF16EncodingLittleEndian);
        }
    
        protected override bool CanReadType(Type type)
        {
            return type == typeof(string);
        }
    
        public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
        {
            string data = null;
            using (var streamReader = new StreamReader(context.HttpContext.Request.Body))
            {
                data = await streamReader.ReadToEndAsync();
            }
            return InputFormatterResult.Success(data);
        }
    }
    

    配置和添加自定义格式化程序支持

    services.AddControllers(opt => opt.InputFormatters.Insert(0, new TextPlainInputFormatter()));
    

    前端代码

    const headers = {
        'Content-Type': 'text/plain'
    };
    
    var json = '{"json_data":"{\"value\":\"hello world\"}';
    
    axios.post('test', json, { headers: headers })
        .then(function (response) {
            //...
    

    测试结果

    【讨论】:

      【解决方案2】:

      更新:

      Demo Source Code Link

      我终于用[FromBody]System.Text.Json.JsonElement解决了问题

      [HttpPost]
      [Route("TestUsingFromBodyAttribute")]
      public object TestUsingFromBodyAttribute([FromBody] System.Text.Json.JsonElement content)
      {
          return content;
      }
      

      因为axios默认Content-Type: application/x-www-form-urlencoded 需要更新Content-Type': 'application/json,否则系统会显示415 unsupported media type

      然后就不能使用string类型或者系统会显示400 bad request

      因为asp.net核心检查Content-Type': 'application/json并使用[FromBody]会自动转换为json对象(System.Text.Json.JsonElement),所以它不能使用字符串类型。

      如果不想编辑axios默认Content-Type: application/x-www-form-urlencoded,则必须设置reqeust data is object not string

      阅读:


      早期答案:

      现在我使用Request.Body而不是Action Parameter来解决问题,但我仍然不知道为什么它不能做到。

      [HttpPost]
      public async Task<IActionResult> Post()
      {
          string json = null;
          using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
          {
              json = await reader.ReadToEndAsync();
          }
          //..etc
      }
      

      【讨论】:

        【解决方案3】:

        您应该使用FromBodyAttribute 进行正确映射。

        【讨论】:

        • 谢谢,我赞成这个,但我发现不只是这个问题
        猜你喜欢
        • 2021-01-11
        • 1970-01-01
        • 2019-04-21
        • 2019-05-15
        • 1970-01-01
        • 2020-09-27
        • 2020-04-12
        • 1970-01-01
        • 2020-10-12
        相关资源
        最近更新 更多