Azure / azure-iot-sdk-csharp

A C# SDK for connecting devices to Microsoft Azure IoT services
Other
463 stars 493 forks source link

Json Format Exception to get payload from Direct Method Request and Twin Json Wrongly formatted #3379

Closed olivakar closed 9 months ago

olivakar commented 10 months ago

Context

Description of the issue

  1. The GetPayload() on DirectMethodRequest results in a JSON Format Exception.
  2. The full twin reported seems to be different in the properties section and appears with keywords like key and value.

Code sample exhibiting the 1st issue

await leafClient.SetDirectMethodCallbackAsync(async req =>
                {
                    _logger.LogInformation("c <- {cid}", deviceId!);
                    _logger.LogDebug("Method {name} called on {did} with rid: {rid}", req.MethodName, deviceId!, req.RequestId);

                    E4K.IoTHubClient.Binders.DirectMethodRequest cmdReq = new(req.MethodName)
                    {
                        CorrelationId = new Guid(req.RequestId),
                        Payload = req.GetPayload()
                    };
                    E4K.IoTHubClient.Binders.DirectMethodResponse cmdResp = await commandClient.InvokeAsync(deviceId!, cmdReq);
                    _logger.LogInformation("c -> {cid}", deviceId!);
                    return new DirectMethodResponse(cmdResp.Status)
                    {
                        Payload = cmdResp.ResponsePayloadBytes!
                    };
                }, stoppingToken).ConfigureAwait(false);

Console log of the 1st issue

Exception thrown: 'System.FormatException' in Newtonsoft.Json.dll

Detailed logs from a console application written to identify the line:

Exception occurred: The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.
Stack trace
   at System.Convert.FromBase64CharPtr(Char* inputPtr, Int32 inputLength)
   at System.Convert.FromBase64CharArray(Char[] inArray, Int32 offset, Int32 length)
   at Newtonsoft.Json.JsonTextReader.ParseReadString(Char quote, ReadType readType)
   at Newtonsoft.Json.JsonTextReader.ParseString(Char quote, ReadType readType)
   at Newtonsoft.Json.JsonTextReader.ReadAsBytes()
   at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value)
   at Microsoft.Azure.Devices.Client.DefaultPayloadConvention.GetObject[T](String jsonObjectAsText)
   at Microsoft.Azure.Devices.Client.DefaultPayloadConvention.GetObject[T](Byte[] objectToConvert)
   at Microsoft.Azure.Devices.Client.DirectMethodRequest.GetPayload()

Output of twin json

twinJson
"{\"desired\":[{\"Key\":\"tick\",\"Value\":132},{\"Key\":\"$version\",\"Value\":4}],\"reported\":[{\"Key\":\"sdkVersion\",\"Value\":\"0.7.3-alpha+95bbc2b3b8\"},{\"Key\":\"sampleItem\",\"Value\":{\"aList\":[1,2,3],\"ADict\":{\"myKey\":\"myValue\"}}},{\"Key\":\"tick\",\"Value\":{\"av\":4,\"ad\":\"tick updated\",\"ac\":200}},{\"Key\":\"$version\",\"Value\":7}]}"

vs output of Desired

"{\"tick\":132,\"$version\":4}"