简体   繁体   中英

Unable to de-serialize a JSON string with a dynamically changing node in C#

My JSON looks like this -

{"0abc34m": {"time": "13 Mar 17, 4:50:02 PM", "pd": "oscar"}}

I am using this code to de-serialize this -

MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(JSONstring));
ms.Position = 0;
DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(Rootobject));
Rootobject myDataTypObj = (Rootobject)jsonSerializer.ReadObject(ms);

I used Visual Studio function "Paste JSON as classes" function to generate these classes -

public class Rootobject
{
    public _00A462 _00a462 { get; set; }
}

public class _00A462
{
    public string time { get; set; }
    public string pd { get; set; }
}

I want to access the "time" and "pd" members of the JSON.

The first part of the JSON is a number that changes every time a new JSON string is received.

I get no errors but my myDataTypObj has null values for _00A462.

I only care about the fields at the second level in the hierarchy.Am I approaching this correctly, what's the problem here?

An easy way is to use JSON.Net and deserialize the JSON to a Dictionary

using Newtonsoft.Json;

class Program
{
    static void Main( string[] args )
    {
        var jsonString = "{\"0abc34m\":{\"time\":\"13 Mar 17, 4:50:02 PM\",\"pd\":\"oscar\"}}";
        Dictionary<string, Data> data;
        data = JsonConvert.DeserializeObject<Dictionary<string, Data>>( jsonString );
        var key = data.First().Key; // 0abc34m
        var time = data.First().Value.TimeString; // 13 Mar 17, 4:50:02 PM
        var pd = data.First().Value.DataString; // oscar
    }
}

public class Data
{
    [JsonProperty("time")]
    public string TimeString { get; set; }
    [JsonProperty("pd")]
    public string DataString { get; set; }
}

Similar to Sir Rufo's Answer using Json.Net to dserialize to a JObject:

DotNetFiddle Example

var json = "{\"0abc34m\": {\"time\": \"13 Mar 17, 4:50:02 PM\", \"pd\": \"oscar\"}}";
dynamic d = JObject.Parse(json);
var values = (d.Properties() as IEnumerable<JProperty>)
  .First()
  .Value as JObject;

var time = DateTime.Parse(((values.Properties() as IEnumerable<JProperty>)
  .First()
  .Value as JValue).Value as string);
var pd = ((values.Properties() as IEnumerable<JProperty>)
  .Skip(1)
  .First()
  .Value as JValue).Value as string;

Console.WriteLine(time);
Console.WriteLine(pd);

Result:

3/13/2017 4:50:02 PM
oscar

If you know JSON exact structure, you can read first (random) number, replace it in your string with known identifier and parse as JSON.

string json_string = ...;
int first_quot_pos = json_string.IndexOf("\"");
int second_quot_pos = json_string.IndexOf("\"", first_quot_pos + 1);
string random_number = json_string.Substring(first_quot_pos, second_quot_pos - first_quot_pos);
string updated_json_string = json_string.Replace(random_number, "number");

Your JSON now should look like this:

{"number": {"time": "13 Mar 17, 4:50:02 PM", "pd": "oscar"}}

And then use updated_json_string :

MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(updated_json_string));
ms.Position = 0;
DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(Rootobject));
Rootobject myDataTypObj = (Rootobject)jsonSerializer.ReadObject(ms);

Your Rootobject should now look like this:

public class Rootobject
{
    public Number number { get; set; }
}

public class Number
{
    public string time { get; set; }
    public string pd { get; set; }
}

Now you have object which have myDataTypObj.number.time and myDataTypObj.number.pd . Also you have random_number .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM