0

I am trying to deserialize the string input in Azure function app. My input is

[{"messageid":1,
"deviceid":"Android",
"temperature":20.0,
"humidity":47.0,
"eventprocessedutctime":"2017-12-01T10:35:57.8331048Z",
"result1":{"temperature":"20","humidity":"47","Scored Labels":"NO","Scored Probabilities":"0.450145334005356"}}]

I tried to run with this code.

#r "Newtonsoft.Json"

using System.Configuration;
using System.Text;
using System.Net;
using Microsoft.Azure.Devices;
using Newtonsoft.Json;

// create proxy
static Microsoft.Azure.Devices.ServiceClient client = ServiceClient.CreateFromConnectionString(ConfigurationManager.AppSettings["myIoTHub"]);

public static async Task<HttpResponseMessage> Run(string input, HttpRequestMessage req, TraceWriter log)
{
    log.Info($"ASA Job: {input}");

    var data = JsonConvert.DeserializeAnonymousType(input, new { deviceid = "" });
    if (!string.IsNullOrEmpty(data?.deviceid))
    {
        string deviceId = data.deviceid;
        // string deviceId = data[0].deviceid;
        log.Info($"Device: {deviceId}");

        // cloud-to-device message 
        var msg = JsonConvert.SerializeObject(new { input });
        var c2dmsg = new Microsoft.Azure.Devices.Message(Encoding.ASCII.GetBytes(msg));

        // send AMQP message
        await client.SendAsync(deviceId, c2dmsg);
    }

    return req.CreateResponse(HttpStatusCode.NoContent);
}

My interest is the deviceid and Scored Labels. But for now I can't even extract one of them. Some more the Scored Labels consists of space. The result1 is the result returned by Azure machine learning so it seems like can't be renamed.

Sam
  • 1,252
  • 5
  • 20
  • 43
  • *JsonConvert.DeserializeAnonymousType failed* -- so, what happened? Was the wrong information returned, or was an exception thrown? If an exception, what is the full `ToString()` output of the exception including the exception type, traceback, message and inner exception (if any)? – dbc Dec 02 '17 at 03:33
  • 1
    @SamTew use this type: var data = JsonConvert.DeserializeAnonymousType(input, new[] { new { deviceid = "", result1 = new { ScoredLabels = ""}}}).SingleOrDefault(); Note, that the property names of the result1 such as 'Scored Labels' and 'Scored Probabilities' can not have a whitespace for clr class. – Roman Kiss Dec 02 '17 at 06:10

1 Answers1

1

Your problem is that your root JSON container is an array, not an object:

  • An array is an ordered collection of values. An array begins with [ (left bracket) and ends with ] (right bracket). Values are separated by , (comma).

  • An object is an unordered set of name/value pairs. An object begins with { (left brace) and ends with } (right brace).

As explained in the Json.NET docs, a JSON array needs to be deserialized into a collection, such as a .Net array. Thus you can do:

var dataArray = JsonConvert.DeserializeAnonymousType(input, new [] { new { deviceid = "" } });
var data = dataArray.SingleOrDefault();

Sample fiddle.

If you find you need to extract more than just one or two properties from your JSON, you may want to create explicit type(s) into which to deserialize. To do this you could use http://json2csharp.com/ or Paste JSON as Classes.

dbc
  • 104,963
  • 20
  • 228
  • 340