问题
Using [FromBody]
string content on an ApiController
in ASP.NET Core 3.0 returns a validation error:
{"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title":"One or more validation errors occurred.",
"status":400,
"traceId":"|9dd96d96-4e64bafba4ba0245.",
"errors":{"$":["The JSON value could not be converted to System.String. Path: $ | LineNumber: 0 | BytePositionInLine: 1."]}}
when the client post data with content-type : application/json
How do I get the raw json data as a string in my api controller in .NET Core 3.0? Without the client having to update its content type?
回答1:
I had to write a custom IInputFormatter
to ensure my body content was always interpreted as a string.
I also was in the situation where updating all of the API clients was infeasible.
The following will ensure that any [FromBody]
parameters will be interpreted as strings, even if they are not quote-wrapped by the caller.
public class JsonStringInputFormatter : TextInputFormatter
{
public JsonStringInputFormatter() : base()
{
SupportedEncodings.Add(UTF8EncodingWithoutBOM);
SupportedEncodings.Add(UTF16EncodingLittleEndian);
SupportedMediaTypes.Add(MediaTypeNames.Application.Json);
}
public override bool CanRead(InputFormatterContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
return context.ModelType == typeof(string);
}
public override async Task<InputFormatterResult> ReadRequestBodyAsync(
InputFormatterContext context, Encoding encoding)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
using (var streamReader = new StreamReader(
context.HttpContext.Request.Body,
encoding))
{
return await InputFormatterResult.SuccessAsync(
(await streamReader.ReadToEndAsync()).Trim('"'));
}
}
}
Trimming quotes from the body allows this to be forwards-compatible for body content that is correctly formatted and quote-wrapped.
Ensure that it is registered in your startup before the System.Text.Json
formatter:
services.AddControllers()
.AddMvcOptions(options =>
{
options.InputFormatters.Insert(
0,
new JsonStringInputFormatter());
});
回答2:
Not sure this help but I think they made some change in .net core 3.0 Newtonsoft.JSON package so you can try this
Install Microsoft.AspNetCore.Mvc.NewtonsoftJson
package.
In your startup.cs add
services.AddControllers().AddNewtonsoftJson();
回答3:
If you are using asp.net core 3.0 then this has built-in JSON support. I have use the following and it works without setting the custom input handler.
[HttpPost]
public async Task<IActionResult> Index([FromBody] JsonElement body)
{
string json = System.Text.Json.JsonSerializer.Serialize(body);
return Ok();
}
回答4:
You need to convert the Json Object to string and then send it to server. Like JSON.stringify(jsonObj).
来源:https://stackoverflow.com/questions/58150652/asp-net-core-3-0-frombody-string-content-returns-the-json-value-could-not-be