JSON related Exception when invoking CreateInvokeMethodRequest
See original GitHub issueThis I can’t explain.
I’ve been running Dapr for over a month and this issue just came up yesterday. It occurs on both 1.0.0 and 1.1.0.
While running the backing service in Tye and debugging via VS Studio 2019, when I invoke a CreateInvokeMethodRequest from a Console app the request is received and successfully processed by the downstream service, however I get the following exception “The JSON value could not be converted to a System.String. Path: $ | LineNumber:0 | BytePositionInLine: 1.”
I was originally seeing this same error within a Blazor app which is why I simplified this down into a console app to diagnose the issue.
What is strange is that I can see that the called service is returning an 200 OK and valid response. I traced the request and response in Fiddler and it too shows everything is normal, in that I also see the 200 response with valid JSON. If I invoke the same API method via Swagger it works fine and returns the correct data.
I called a number of other API calls, some that return complex types while others that return simple string and all throw the same exception.
Within the exception the Response object shows Status Code 200
Here is the exception details;
Here is the client code…
// Create Dapr Client using the URI for CoreServices Dapr sidecar
var daprClientBuilder = new DaprClientBuilder();
daprClientBuilder = daprClientBuilder.UseHttpEndpoint("http://localhost:62209/");
var _daprClient = daprClientBuilder.Build();
// Create GetAll Request with simple query
var GetAllRequest = new NextWare.ProductPortal.CoreServices.Organization.ViewModels.GetAllRequest { Query = @"{""from"":0,""size"":3}" };
// Create an instance of Organization service with Dapr client
var _organizationService = new NextWare.ProductPortal.CoreServices.AggregateRoots.Organization.DaprClientServices.OrganizationDaprService(_daprClient);
// Create GetAll Request with simple query
var GetRequest = new NextWare.ProductPortal.CoreServices.Organization.ViewModels.GetRequest { OrganizationId = new NextWare.ProductPortal.CoreServices.Organization.ViewModels.OrganizationId("ad13d371-c3f5-4471-b969-179a9fc11530") };
try
{
var httpRequest = _daprClient.CreateInvokeMethodRequest(httpMethod: System.Net.Http.HttpMethod.Put, appId: "nextware-productportal-coreservices-api", methodName: "api/v1.0.0/Organization/TypedGet", data: GetRequest);
//GrpcCallContextFactory.InjectHeaders(context, httpRequest);
var response = await _daprClient.InvokeMethodAsync<string>(httpRequest, CancellationToken.None);
}
catch (Exception ex)
{
Serilog.Log.Error("Exception in OrganizationService.GetAll {ex}", ex);
throw;
}
Here is the stack trace from the exception…
at System.Text.Json.ThrowHelper.ReThrowWithPath(ReadStack& state, Utf8JsonReader& reader, Exception ex)
at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
at System.Text.Json.JsonSerializer.ReadCore[TValue](JsonConverter jsonConverter, Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
at System.Text.Json.JsonSerializer.ReadCore[TValue](JsonReaderState& readerState, Boolean isFinalBlock, ReadOnlySpan`1 buffer, JsonSerializerOptions options, ReadStack& state, JsonConverter converterBase)
at System.Text.Json.JsonSerializer.<ReadAsync>d__20`1.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Threading.Tasks.ValueTask`1.get_Result()
at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable`1.ConfiguredValueTaskAwaiter.GetResult()
at System.Net.Http.Json.HttpContentJsonExtensions.<ReadFromJsonAsyncCore>d__3`1.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Dapr.Client.DaprClientGrpc.<InvokeMethodAsync>d__26`1.MoveNext()
Here is the Fiddler response…
From what I can tell the actual response is good. Why do I get this exception?
Issue Analytics
- State:
- Created 2 years ago
- Comments:6
I think there’s some confusion about what
_daprClient.InvokeMethodAsync<string>
will do. This method will use System.Text.Json to read the response body (it’s a JSON object) and try to read it as a JSON string - which it is not. This is not a Dapr issue, it’s the behavior of the JSON serializer.The hint is here:![image](https://user-images.githubusercontent.com/1430011/113917123-adfea480-9795-11eb-81bf-414c79cbaec1.png)
You could reproduce this with code like the following:
The payload (
json
) contains a JSON object, it can’t be read as if it were a JSON string.How to proceed here depends on what you want - if you want to get the raw text of the response, then you could use:
This will give you an
HttpResponseMessage
and you can do whatever you like with the content.If instead you expect the response payload to be an object, and want to read it as an object, then replace
_daprClient.InvokeMethodAsync<string>(...)
with_daprClient.InvokeMethodAsync<your type here>(...)
If you want to work with JSON in a weakly-typed way, you could use
JsonElement
,JsonDocument
orobject
as the type.Ran into this, and DaprClient.CreateInvokeHttpClient feels more cleaner as in the below example, Invoke Service Http Client Example