question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

JSON related Exception when invoking CreateInvokeMethodRequest

See original GitHub issue

This 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;

image

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…

image

From what I can tell the actual response is good. Why do I get this exception?

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:6

github_iconTop GitHub Comments

1reaction
rynowakcommented, Apr 7, 2021

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

You could reproduce this with code like the following:

var obj = new { Color = "red" } ;
var json = JsonSerializer.Serialize(obj);
var text = JsonSerializer.Deserialize<string>(json)

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:

_daprClient.InvokeMethodWithResponseAsync(...)

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 or object as the type.

0reactions
sravimohancommented, Dec 5, 2021

Ran into this, and DaprClient.CreateInvokeHttpClient feels more cleaner as in the below example, Invoke Service Http Client Example

Read more comments on GitHub >

github_iconTop Results From Across the Web

How-To: Invoke services using HTTP | Dapr Docs
Build(); //Using Dapr SDK to invoke a method var result = client.CreateInvokeMethodRequest(HttpMethod.Get, "checkout", "checkout/" + orderId); await client.
Read more >
System.Text.Json.JsonException: The JSON value could ...
I'm using Ubuntu and dotnet 3.1, running vscode's c# extension. I need to create a List from a JSON file, my controller will...
Read more >
The Dapr service invocation building block
A description of the service invocation building block, its features, benefits, and how to apply it.
Read more >
Dapr for .NET Developers - GitHub
A secondary audience is technical decision-makers who plan to choose whether to build their applications using a cloud-native approach. How you ...
Read more >
JsonException (Java(TM) EE 7 Specification APIs)
Constructs a new runtime exception with the specified detail message. The cause is not initialized, and may subsequently be initialized by a call...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found