Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSharpNotesForProfessionals.pdf
Скачиваний:
65
Добавлен:
20.05.2023
Размер:
6.12 Mб
Скачать

Chapter 83: Using json.net

Using JSON.net JsonConverter class.

Section 83.1: Using JsonConverter on simple values

Example using JsonCoverter to deserialize the runtime property from the api response into a Timespan Object in the Movies model

JSON (http://www.omdbapi.com/?i=tt1663662)

{

Title: "Pacific Rim", Year: "2013",

Rated: "PG-13", Released: "12 Jul 2013", Runtime: "131 min",

Genre: "Action, Adventure, Sci-Fi", Director: "Guillermo del Toro",

Writer: "Travis Beacham (screenplay), Guillermo del Toro (screenplay), Travis Beacham (story)", Actors: "Charlie Hunnam, Diego Klattenhoff, Idris Elba, Rinko Kikuchi",

Plot: "As a war between humankind and monstrous sea creatures wages on, a former pilot and a trainee are paired up to drive a seemingly obsolete special weapon in a desperate effort to save the world from the apocalypse.",

Language: "English, Japanese, Cantonese, Mandarin", Country: "USA",

Awards: "Nominated for 1 BAFTA Film Award. Another 6 wins & 46 nominations.", Poster:

"https://images-na.ssl-images-amazon.com/images/M/MV5BMTY3MTI5NjQ4Nl5BMl5BanBnXkFtZTcwOTU1OTU0OQ@@. _V1_SX300.jpg",

Ratings: [{

Source: "Internet Movie Database", Value: "7.0/10"

},

{

Source: "Rotten Tomatoes", Value: "71%"

},

{

Source: "Metacritic", Value: "64/100"

}

],

Metascore: "64", imdbRating: "7.0", imdbVotes: "398,198", imdbID: "tt1663662", Type: "movie",

DVD: "15 Oct 2013", BoxOffice: "$101,785,482.00",

Production: "Warner Bros. Pictures", Website: "http://pacificrimmovie.com", Response: "True"

}

Movie Model

using Project.Serializers; using Newtonsoft.Json; using System;

using System.Collections.Generic;

GoalKicker.com – C# Notes for Professionals

473

using System.Linq;

using System.Runtime.Serialization; using System.Threading.Tasks;

namespace Project.Models

{

[DataContract] public class Movie

{

public Movie() { }

[DataMember]

public int Id { get; set; }

[DataMember]

public string ImdbId { get; set; }

[DataMember]

public string Title { get; set; }

[DataMember]

public DateTime Released { get; set; }

[DataMember] [JsonConverter(typeof(RuntimeSerializer))] public TimeSpan Runtime { get; set; }

}

}

RuntimeSerializer

using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System;

using System.Collections.Generic; using System.Linq;

using System.Text.RegularExpressions; using System.Threading.Tasks;

namespace Project.Serializers

{

public class RuntimeSerializer : JsonConverter

{

public override bool CanConvert(Type objectType)

{

return objectType == typeof(TimeSpan);

}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)

{

if (reader.TokenType == JsonToken.Null) return null;

JToken jt = JToken.Load(reader);

String value = jt.Value<String>();

Regex rx = new Regex("(\\s*)min$"); value = rx.Replace(value, (m) => "");

int timespanMin;

if(!Int32.TryParse(value, out timespanMin))

GoalKicker.com – C# Notes for Professionals

474

{

throw new NotSupportedException();

}

return new TimeSpan(0, timespanMin, 0);

}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)

{

serializer.Serialize(writer, value);

}

}

}

Calling It

Movie m = JsonConvert.DeserializeObject<Movie>(apiResponse));

Section 83.2: Collect all fields of JSON object

using Newtonsoft.Json.Linq; using System.Collections.Generic;

public class JsonFieldsCollector

{

private readonly Dictionary<string, JValue> fields;

public JsonFieldsCollector(JToken token)

{

fields = new Dictionary<string, JValue>(); CollectFields(token);

}

private void CollectFields(JToken jToken)

{

switch (jToken.Type)

{

case JTokenType.Object:

foreach (var child in jToken.Children<JProperty>()) CollectFields(child);

break;

case JTokenType.Array:

foreach (var child in jToken.Children()) CollectFields(child);

break;

case JTokenType.Property: CollectFields(((JProperty) jToken).Value); break;

default:

fields.Add(jToken.Path, (JValue)jToken); break;

}

}

public IEnumerable<KeyValuePair<string, JValue>> GetAllFields() => fields;

}

Usage:

var json = JToken.Parse(/* JSON string */);

var fieldsCollector = new JsonFieldsCollector(json);

GoalKicker.com – C# Notes for Professionals

475

var fields = fieldsCollector.GetAllFields();

foreach (var field in fields) Console.WriteLine($"{field.Key}: '{field.Value}'");

Demo

For this JSON object

{

"User": "John", "Workdays": {

"Monday": true, "Tuesday": true, "Friday": false

}, "Age": 42

}

expected output will be:

User: 'John'

Workdays.Monday: 'True'

Workdays.Tuesday: 'True'

Workdays.Friday: 'False'

Age: '42'

GoalKicker.com – C# Notes for Professionals

476