简体   繁体   中英

Parse json in c# when each name/value pair isn't sent

I'm implementing a client/server between a tablet and a PC and I need to pass data back and forth. After doing some reading json looks like it may be a simple, defined interface to use. I'm using Newtonsoft.Json in my project.

My understanding is that unless it is defined as required in the schema, that each name/value pair doesn't have to be in each message. If this is true, I'm struggling with how to parse the json object after deserializing it to determine the names that were sent in the message.

For example, If I'm sending weather data and can send json data that looks like

{  "isRaining": false,
   "isSnowing": false,
   "temp": 50.0
}

If I always send all three, then I can create a class that has the same members and assign the data when I deserialize it.

public class Weather
{
    public bool isRaining { get; set; }
    public bool isSnowing { get; set; }
    public float temp { get; set; }
}

Weather readWeather = JsonConvert.DeserializeObject<Weather>(data);

But I'd like to not have to send ALL the data each transmission. I really only want to know if something has changed, and then get only the temp name/value pair if the temp has gone up, if whether it's raining or snowing hasn't changed, I don't want to get that data.

It looks like that at least deserializing the data this way, I can't do a for each loop to see what names exist. Is there any way to do this? Or am I stuck sending all the data all the time?

I will be sending more data in my actual implementation, I only put three pairs here for simplicity.

If you make your properties nullable, it is optional to send them

public class Weather
{        
    public bool? isRaining { get; set; }
    public bool? isSnowing { get; set; }
    public float? temp { get; set; }
}

This will now quite happily accept this json:

{  
   "isSnowing": false,
   "temp": 50.0
}

And you can test the result with HasValue

var hasRainData = readWeather.isRaining.HasData;

Live example: http://rextester.com/HCZG76360

You could make the properties optional using the Nullable<> data type:

public class Weather
{
    public bool? isRaining { get; set; }
    public bool? isSnowing { get; set; }
    public float? temp { get; set; }
}
Weather readWeather = JsonConvert.DeserializeObject<Weather>(data);
if(readWeather.isRaining != null)
{
    Console.WriteLine("It is " + (readWeather.isRaining.Value ? "now raining" : "no longer raining"));
}

You can use JsonReader to do more controlled deserialization and figure out which properties are actually present Json.Net Reader official example

JsonTextReader reader = new JsonTextReader(new StringReader(json));
while (reader.Read())
{
    if (reader.Value != null)
    {
        Console.WriteLine("Token: {0}, Value: {1}", reader.TokenType, reader.Value);
    }
    else
    {
        Console.WriteLine("Token: {0}", reader.TokenType);
    }
}

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