ASP.NET Core 3.1 Web Api HttpPost Action参数无法接收axios application/json HttpPost传递数据
ASP.NET Core 3.1 Web Api HttpPost Action parameter can't receive axios application/json HttpPost passing data
我以前用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();
}
}
更新:
我终于用[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
}
您应该使用 FromBodyAttribute 进行正确映射。
public async Task Post(string json)
如果您想使用数据从前端发出 HTTP 请求并将其绑定到 字符串类型 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) {
//...
测试结果
我以前用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();
}
}
更新:
我终于用[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
}
您应该使用 FromBodyAttribute 进行正确映射。
public async Task Post(string json)
如果您想使用数据从前端发出 HTTP 请求并将其绑定到 字符串类型 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) {
//...
测试结果