JSON Handling
💡 Vad är JSON?
JSON (JavaScript Object Notation) är som språket som program pratar med varandra.
Tänk dig att du ska beställa pizza per telefon till Italien. Du pratar svenska, pizzabagaren pratar italienska. JSON är som en tolk som översätter mellan er - enkelt, tydligt och alla förstår det.
🎯 TL;DR
JSON = textformat för att skicka data mellan program. Lätt att läsa för både människor och datorer. C-Sharp kan automatiskt konvertera objekt ↔ JSON.
📋 Efter att ha läst detta kommer du att kunna
- Förstå JSON-syntax och struktur
- Serialisera C-Sharp-objekt till JSON
- Deserialiera JSON till C-Sharp-objekt
- Hantera komplexa JSON-strukturer
- Konfigurera JSON-inställningar i ASP.NET
🔧 Grundprinciper
Princip 1: Text-baserat format
JSON är bara text - kan skickas över internet och läsas av alla språk.
Princip 2: Hierarkisk struktur
Objekt kan innehålla andra objekt och listor.
Princip 3: Typsäkert
Stöder strings, numbers, booleans, null, objects och arrays.
💭 JSON-syntax
💬 JSON följer enkla regler:
GRUNDTYPER:
- Strings: "text med citattecken"
- Numbers: 42, 3.14
- Booleans: true, false
- Null: null
STRUKTURER:
- Object: { "key": "value", "another": 123 }
- Array: [ "item1", "item2", "item3" ]
{
"name": "Marcus",
"age": 35,
"isTeacher": true,
"address": {
"street": "Kodgatan 1",
"city": "Göteborg"
},
"hobbies": ["programming", "teaching", "coffee"],
"spouse": null
}
🚀 JSON i C-Sharp - från enkelt till avancerat
🟢 Grundläggande serialisering/deserialisering
using System.Text.Json;
// C-Sharp-klass
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public bool IsTeacher { get; set; }
}
// Objekt till JSON (Serialization)
var person = new Person
{
Name = "Marcus",
Age = 35,
IsTeacher = true
};
string json = JsonSerializer.Serialize(person);
Console.WriteLine(json);
// Output: {"Name":"Marcus","Age":35,"IsTeacher":true}
// JSON till objekt (Deserialization)
string jsonString = """{"Name":"Anna","Age":28,"IsTeacher":false}""";
Person anna = JsonSerializer.Deserialize<Person>(jsonString);
Console.WriteLine($"{anna.Name} är {anna.Age} år");
// Output: Anna är 28 år
🟡 Komplexa strukturer och listor
public class Address
{
public string Street { get; set; }
public string City { get; set; }
public string PostalCode { get; set; }
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Address Address { get; set; }
public List<string> Hobbies { get; set; } = new();
public Dictionary<string, object> Metadata { get; set; } = new();
}
// Skapa komplex struktur
var person = new Person
{
Name = "Marcus",
Age = 35,
Address = new Address
{
Street = "Kodgatan 1",
City = "Göteborg",
PostalCode = "41234"
},
Hobbies = ["programming", "teaching", "coffee"],
Metadata = {
["employeeId"] = 12345,
["department"] = "Education",
["isActive"] = true
}
};
// Serialisera till JSON med pretty printing
var options = new JsonSerializerOptions
{
WriteIndented = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
string json = JsonSerializer.Serialize(person, options);
Console.WriteLine(json);
Output:
{
"name": "Marcus",
"age": 35,
"address": {
"street": "Kodgatan 1",
"city": "Göteborg",
"postalCode": "41234"
},
"hobbies": ["programming", "teaching", "coffee"],
"metadata": {
"employeeId": 12345,
"department": "Education",
"isActive": true
}
}
🔴 Avancerat: Anpassning och attribut
using System.Text.Json.Serialization;
public class Product
{
[JsonPropertyName("product_id")]
public int Id { get; set; }
[JsonPropertyName("product_name")]
public string Name { get; set; }
[JsonIgnore]
public string InternalNotes { get; set; } // Kommer inte med i JSON
[JsonPropertyName("price")]
public decimal Price { get; set; }
[JsonPropertyName("created_at")]
public DateTime CreatedAt { get; set; }
[JsonPropertyName("tags")]
public List<string> Tags { get; set; } = new();
// Conditional serialization
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? OptionalField { get; set; }
}
// Custom converter för DateTime
public class CustomDateTimeConverter : JsonConverter<DateTime>
{
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return DateTime.ParseExact(reader.GetString()!, "yyyy-MM-dd", null);
}
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString("yyyy-MM-dd"));
}
}
// Använd custom converter
var options = new JsonSerializerOptions();
options.Converters.Add(new CustomDateTimeConverter());
var product = new Product
{
Id = 123,
Name = "Laptop",
InternalNotes = "This won't appear in JSON",
Price = 15999.99m,
CreatedAt = DateTime.Now,
Tags = ["electronics", "computers"]
};
string json = JsonSerializer.Serialize(product, options);
🌐 JSON i ASP.NET Core API:er
🔧 Konfigurera JSON i Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
options.SerializerOptions.WriteIndented = true;
options.SerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
});
// För controllers
builder.Services.Configure<JsonOptions>(options =>
{
options.SerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
options.SerializerOptions.WriteIndented = true;
});
📡 API Controller med JSON
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
// ASP.NET serialiserar automatiskt till JSON
[HttpGet]
public ActionResult<List<Product>> GetProducts()
{
var products = new List<Product>
{
new() { Id = 1, Name = "Laptop", Price = 15999.99m },
new() { Id = 2, Name = "Mouse", Price = 299.99m }
};
return Ok(products); // Blir automatiskt JSON
}
// ASP.NET deserialiserar automatiskt från JSON
[HttpPost]
public ActionResult<Product> CreateProduct([FromBody] Product product)
{
// product är redan deserialiserat från JSON i request body
product.Id = GenerateNewId();
// Returvärdet blir automatiskt JSON
return CreatedAtAction(nameof(GetProduct), new { id = product.Id }, product);
}
// Manuell JSON-hantering vid behov
[HttpPost("manual")]
public async Task<ActionResult> CreateProductManual()
{
// Läs raw JSON från request
using var reader = new StreamReader(Request.Body);
string jsonBody = await reader.ReadToEndAsync();
try
{
var product = JsonSerializer.Deserialize<Product>(jsonBody);
// Bearbeta product...
// Returnera JSON manuellt
var responseJson = JsonSerializer.Serialize(new { success = true, id = product.Id });
return Content(responseJson, "application/json");
}
catch (JsonException ex)
{
return BadRequest(new { error = "Invalid JSON", details = ex.Message });
}
}
}
🔍 Felsökning och vanliga problem
⚠️ Vanliga JSON-misstag
// MISSTAG 1: Case-sensitivity
string json = """{"name": "Marcus"}""";
// Om C-Sharp-property heter "Name" (stor N) kan deserialisering misslyckas
// LÖSNING: Konfigurera naming policy
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
// MISSTAG 2: Cirkulära referenser
public class Parent
{
public string Name { get; set; }
public List<Child> Children { get; set; }
}
public class Child
{
public string Name { get; set; }
public Parent Parent { get; set; } // Cirkulär referens!
}
// LÖSNING: Använd JsonIgnore eller ReferenceHandler
var options = new JsonSerializerOptions
{
ReferenceHandler = ReferenceHandler.IgnoreCycles
};
🛠️ JSON-validering
public static bool IsValidJson(string jsonString)
{
try
{
JsonDocument.Parse(jsonString);
return true;
}
catch (JsonException)
{
return false;
}
}
// Robust deserialisering
public static T? SafeDeserialize<T>(string json) where T : class
{
try
{
return JsonSerializer.Deserialize<T>(json);
}
catch (JsonException ex)
{
Console.WriteLine($"JSON Error: {ex.Message}");
return null;
}
}
📚 Sammanfattning
JSON är lingua franca för webb-API:er:
- Text-format som alla förstår
- Automatisk serialisering i ASP.NET Core
- Konfigurerbar med attribut och options
- Typesäker konvertering C-Sharp ↔ JSON
- Robust felhantering är viktigt
🎯 Övningar
- 🟢 Grundläggande: Skapa en Person-klass och konvertera till/från JSON
- 🟡 Utmanande: Bygg ett API som tar emot JSON och sparar det som C-Sharp-objekt
😄 Obligatorisk dad joke
Varför är JSON så populär bland utvecklare? För att det alltid är välformulerat och aldrig parsar ord med någon! 📝