Azure/azure-iot-sdk-csharp

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

olivakar opened this issue · 0 comments

Context

  • SDK version used: 2.0.0-preview007

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}"