JSON-serialisering

JSON är Javascript Object Notation, så för den som är van vid Javascript kanske det ser bekant ut.

Här hittar du Microsofts officiella dokumentation.

Bibliotek

Lägg till detta using-statement:

using System.Text.Json;

Klassdesign

Klassen vars instanser ska kunna serialiseras/deserialiseras måste vara public.

Pokemon.cs
public class Pokemon
{
  public string name {get; set;}
  public int id {get; set;}
  public bool is_default {get; set;}
}

Det är också enbart publika variabler samt properties med publika getters och setters som serialiseras.

Om du ska deserialisera JSON-kod som du får från något annat ställe och inte designat själv, så behöver du vara noga med att matcha namnet på dina publika variabler/properties mot JSON-kodens. Serialiseringsprocessen är normalt känslig vad gäller stora och små bokstäver, men du kan ändra på detta (rekommenderas!).

public class Pokemon
{
  public string name {get; set;}
  public int id {get; set;}
  public bool is_default {get; set;}
}

JsonSerializer.Serialize<>()

Används för att serialisera ett objekt till en JSON-string.

Pokemon poke = new Pokemon()
{
  Name = "Ditto",
  Id = 132,
  IsDefault = true,
  Species = new PokemonSpecies() {
    Name = "ditto",
    Url = "https://pokeapi.co/api/v2/pokemon-species/132/"
  }
};

string json = JsonSerializer.Serialize<Pokemon>(poke);

Denna string kan sedan lagras i en textfil eller t.ex. skickas som svar på ett REST-anrop.

JsonSerializerOptions

Genom att skicka in ett JsonSerializerOptions-objekt kan man ge mer detaljerade instruktioner till serializern.

JsonSerializerOptions options = new ()
{
  // Ger snygg, indenterad JSON-kod
  WriteIndented = true,
  // Omvandlar alla property-namn till snake_case
  PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower // döper om properties
};

string json = JsonSerializer.Serialize<Pokemon>(poke, options);

I JSON används oftast snake_case, medan C# ju använder camelCase eller PascalCase.

OBS: SnakeCaseLower introducerades i dotnet 8!

JsonSerializer.Deserialize<>()

Används för att deserialisera ett objekt från en JSON-string.

// jsonString innehåller json-data. Den kan t.ex. läsas in från en json-fil
// eller hämtas från en REST-server.
Pokemon ditto = JsonSerializer.Deserialize<Pokemon>(jsonString);

Attribut

Mer om attribut här.

OBS: dessa kräver att du inkluderar System.Text.Json.Serialization.

[JsonIgnore]

Används för att se till så att en variabel eller property på C#-sidan inte serialiseras till JSON.

Pokemon.cs
using System.Text.Json.Serialization;

public class Pokemon
{
  public string Name {get; set;}
  public bool IsDefault {get; set;}
  
  [JsonIgnore]
  public int CurrentHp {get; set;}
}

[JsonPropertyName()]

Med attributet [JsonPropertyName()] kan man bestämma att en C#-klass' property ska matchas mot ett JSON-värde med annat namn.

Pokemon.cs
using System.Text.Json.Serialization;

class Pokemon
{
  public string Name {get; set;}
  public int Id {get; set;}
  
  [JsonPropertyName("is_default")]
  public bool IsDefault {get; set;}
}

Deserialisering av listor

Ibland beskriver JSON-kod listor av objekt eller värden. De kännetecknas av att ge omges av hakparenteser [].

{
  "name": "ditto",
  "forms":
  [
    "Ditto",
    "Exempel"
  ]
}

För att deserialisera dessa, skapa helt enkelt publika listor i klassen.

Pokemon.cs
class Pokemon
{
  [JsonPropertyName("name")]
  public string Name {get; set;}
  
  [JsonPropertyName("forms")]
  public List<string> Forms {get; set;}
}

Deserialisering av objekt i flera led

Ibland beskriver JSON-kod objekt som innehåller andra objekt.

{
  "name": "ditto",
  "species":
  {
    "name": "ditto",
    "url": "https://pokeapi.co/api/v2/pokemon-species/132/"
  }
}

För att deserialisera dessa, skapa klasser som beskriver de inre objekten.

PokemonSpecies.cs
class PokemonSpecies
{
  [JsonPropertyName("name")]
  public string Name {get; set;}
  
  [JsonPropertyName("url")]
  public string Url {get; set;}
}
Pokemon.cs
class Pokemon
{
  [JsonPropertyName("name")]
  public string Name {get; set;}
  
  [JsonPropertyName("species")]
  public PokemonSpecies Species {get; set;}
}

Last updated