Sam
Sam

Reputation: 1327

C# JsonConvert.DeserializeAnonymousType failed

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.

Upvotes: 0

Views: 678

Answers (1)

dbc
dbc

Reputation: 116670

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.

Upvotes: 1

Related Questions