Reputation: 397
I have a React TypeScript application which makes a call to a C# ASP.NET Core 7 Minimal API.
The call from the React app looks like this:
const resp = await Client.post('https://localhost:7196/institutions', JSON.stringify(doc));
Client
is defined as follows:
import axios from 'axios';
import { jsonrepair } from 'jsonrepair';
export class Client {
static async post(url: string, jsonData: string) {
const headers = {
headers: { 'Content-Type': 'application/json' }
};
try {
const response = await axios.post(url, jsonrepair(jsonData), headers );
return response?.data;
} catch (e) {
return e.message;
}
}
}
The relevant C# code in my minimal API is as follows:
app.MapPost("/institutions", async ([FromBody]string instJson, InstitutionDb instDb, [FromHeader(Name = "Content-Type")] string contentType) =>
{
var inst = JsonSerializer.Deserialize<Institution>(instJson);
if (inst != null)
{
instDb.Institutions.Add(inst);
await instDb.SaveChangesAsync();
return Results.Created($"/institutions/{inst.Id}", inst);
}
return null;
});
However, when executing it - even after verifying that the JSON being passed is legitimate (after being cleaned with the TypeScript jsonrepair
utility), I receive the following error:
Microsoft.AspNetCore.Http.BadHttpRequestException: Failed to read parameter "string instJson" from the request body as JSON. ---> System.Text.Json.JsonException: The JSON value could not be converted to System.String. Path: $ | LineNumber: 0 | BytePositionInLine: 1. ---> System.InvalidOperationException: Cannot get the value of a token type 'StartObject' as a string. at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_ExpectedString(JsonTokenType tokenType) at System.Text.Json.Utf8JsonReader.GetString() at System.Text.Json.Serialization.JsonConverter
1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value) at System.Text.Json.Serialization.JsonConverter
1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state) --- End of inner exception stack trace --- at System.Text.Json.ThrowHelper.ReThrowWithPath(ReadStack& state, Utf8JsonReader& reader, Exception ex) at System.Text.Json.Serialization.JsonConverter1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state) at System.Text.Json.Serialization.JsonConverter
1.ReadCoreAsObject(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state) at System.Text.Json.JsonSerializer.ReadCore[TValue](Utf8JsonReader& reader, JsonTypeInfo jsonTypeInfo, ReadStack& state) at System.Text.Json.JsonSerializer.ContinueDeserialize[TValue](ReadBufferState& bufferState, JsonReaderState& jsonReaderState, ReadStack& readStack, JsonTypeInfo jsonTypeInfo) at System.Text.Json.JsonSerializer.ReadFromStreamAsync[TValue](Stream utf8Json, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken) at Microsoft.AspNetCore.Http.HttpRequestJsonExtensions.ReadFromJsonAsync(HttpRequest request, Type type, JsonSerializerOptions options, CancellationToken cancellationToken) at Microsoft.AspNetCore.Http.HttpRequestJsonExtensions.ReadFromJsonAsync(HttpRequest request, Type type, JsonSerializerOptions options, CancellationToken cancellationToken) at Microsoft.AspNetCore.Http.RequestDelegateFactory.g__TryReadBodyAsync|90_0(HttpContext httpContext, Type bodyType, String parameterTypeName, String parameterName, Boolean allowEmptyRequestBody, Boolean throwOnBadRequest) --- End of inner exception stack trace --- at Microsoft.AspNetCore.Http.RequestDelegateFactory.Log.InvalidJsonRequestBody(HttpContext httpContext, String parameterTypeName, String parameterName, Exception exception, Boolean shouldThrow) at Microsoft.AspNetCore.Http.RequestDelegateFactory.g__TryReadBodyAsync|90_0(HttpContext httpContext, Type bodyType, String parameterTypeName, String parameterName, Boolean allowEmptyRequestBody, Boolean throwOnBadRequest) at Microsoft.AspNetCore.Http.RequestDelegateFactory.<>c__DisplayClass90_2.<b__2>d.MoveNext() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
The interesting thing is that if I debug and set a breakpoint on (or inside) app.MapPost()
, the breakpoint does not get hit.
Why is this happening? Why is the endpoint failing, even with valid JSON and the content-type header being set correctly? Why am I unable to set a breakpoint in my C# code?
Any suggestions? I have searched this error extensively on StackOverflow and elsewhere. Others have reported this error but none of the solutions I've tried have worked for me.
Upvotes: 0
Views: 2595
Reputation: 43931
you sending your data as a json, not as a string, so changed the header
app.MapPost("/institutions", async ([FromBody]Institution inst)
and remove deserialization code
Upvotes: 0