Úkol JSON

Site: Moodle ZČU
Course: BP Luboš Dokulil Sada rozšiřujících úloh v Blazor pro předmět Programování 2
Book: Úkol JSON
Printed by: Nepřihlášený host
Date: Sunday, 18 October 2026, 3:07 AM

1. Zadání

Co je cílem zadání?

  • Vytvoření datové třídy Film, jejíž vlastnosti svým názvem přesně odpovídají struktuře a klíčům v externím JSON souboru.
  • Asynchronní načtení dat z lokálního souboru pomocí HTTP klienta a jejich automatické namapování do pole objektů ihned při startu komponenty.
  • Dynamické vykreslení úspěšně načtené kolekce filmů do přehledné HTML tabulky pomocí cyklu.

Zadání

Nejprve definujte C# třídu Film, která bude sloužit jako datová šablona (s vlastnostmi Id, Nazev, RokVydani a Reziser). Následně ve veřejné složce wwwroot vytvořte podsložku data a umístěte do ní soubor filmy.json, který bude obsahovat pole alespoň 30 vašich oblíbených filmů ve formátu JSON.

V Razor komponentě si pomocí direktivy @inject připojte systémovou službu HttpClient. Pro automatické načtení dat využijte vestavěnou metodu životního cyklu OnInitializedAsync(), uvnitř které pomocí příkazu await Http.GetFromJsonAsync() stáhnete váš lokální soubor a rovnou ho převedete do pole připravených C# objektů.

Získané informace následně projděte cyklem @foreach a přehledně je vypište do HTML tabulky. Nezapomeňte v uživatelském rozhraní elegantně ošetřit také stav, kdy se data teprve stahují do paměti, například dočasným zobrazením textu „Načítám...“.

Příklad, jak by mohla stránka vypadat:

Pokud se okno nenačetlo, klikněte zde.

2. JSON data

Zde je adresářová struktura.

Zde je seznam filmů zapsaný v JSON formátu.

[
  {
    "id": 1,
    "nazev": "Pelíšky",
    "rokVydani": 1999,
    "reziser": "Jan Hřebejk"
  },
  {
    "id": 2,
    "nazev": "Inception",
    "rokVydani": 2010,
    "reziser": "Christopher Nolan"
  },
  {
    "id": 3,
    "nazev": "Pán prstenů: Společenstvo Prstenu",
    "rokVydani": 2001,
    "reziser": "Peter Jackson"
  },
  {
    "id": 4,
    "nazev": "Vykoupení z věznice Shawshank",
    "rokVydani": 1994,
    "reziser": "Frank Darabont"
  },
  {
    "id": 5,
    "nazev": "Kmotr",
    "rokVydani": 1972,
    "reziser": "Francis Ford Coppola"
  },
  {
    "id": 6,
    "nazev": "Temný rytíř",
    "rokVydani": 2008,
    "reziser": "Christopher Nolan"
  },
  {
    "id": 7,
    "nazev": "Pulp Fiction: Historky z podsvětí",
    "rokVydani": 1994,
    "reziser": "Quentin Tarantino"
  },
  {
    "id": 8,
    "nazev": "Forrest Gump",
    "rokVydani": 1994,
    "reziser": "Robert Zemeckis"
  },
  {
    "id": 9,
    "nazev": "Klub rváčů",
    "rokVydani": 1999,
    "reziser": "David Fincher"
  },
  {
    "id": 10,
    "nazev": "Matrix",
    "rokVydani": 1999,
    "reziser": "Lana Wachowski, Lilly Wachowski"
  },
  {
    "id": 11,
    "nazev": "Samotáři",
    "rokVydani": 2000,
    "reziser": "David Ondříček"
  },
  {
    "id": 12,
    "nazev": "Kolja",
    "rokVydani": 1996,
    "reziser": "Jan Svěrák"
  },
  {
    "id": 13,
    "nazev": "Spalovač mrtvol",
    "rokVydani": 1968,
    "reziser": "Juraj Herz"
  },
  {
    "id": 14,
    "nazev": "Star Wars: Epizoda V - Impérium vrací úder",
    "rokVydani": 1980,
    "reziser": "Irvin Kershner"
  },
  {
    "id": 15,
    "nazev": "Pán prstenů: Návrat krále",
    "rokVydani": 2003,
    "reziser": "Peter Jackson"
  },
  {
    "id": 16,
    "nazev": "Návrat do budoucnosti",
    "rokVydani": 1985,
    "reziser": "Robert Zemeckis"
  },
  {
    "id": 17,
    "nazev": "Terminátor 2: Den zúčtování",
    "rokVydani": 1991,
    "reziser": "James Cameron"
  },
  {
    "id": 18,
    "nazev": "Vetřelec",
    "rokVydani": 1979,
    "reziser": "Ridley Scott"
  },
  {
    "id": 19,
    "nazev": "Schindlerův seznam",
    "rokVydani": 1993,
    "reziser": "Steven Spielberg"
  },
  {
    "id": 20,
    "nazev": "Jurský park",
    "rokVydani": 1993,
    "reziser": "Steven Spielberg"
  },
  {
    "id": 21,
    "nazev": "Pátý element",
    "rokVydani": 1997,
    "reziser": "Luc Besson"
  },
  {
    "id": 22,
    "nazev""Ostře sledované vlaky",
    "rokVydani": 1966,
    "reziser": "Jiří Menzel"
  },
  {
    "id": 23,
    "nazev": "Dvanáct rozhněvaných mužů",
    "rokVydani": 1957,
    "reziser": "Sidney Lumet"
  },
  {
    "id": 24,
    "nazev": "Přelet nad kukaččím hnízdem",
    "rokVydani": 1975,
    "reziser": "Miloš Forman"
  },
  {
    "id": 25,
    "nazev": "Amadeus",
    "rokVydani": 1984,
    "reziser": "Miloš Forman"
  },
  {
    "id": 26,
    "nazev": "Vesničko má středisková",
    "rokVydani": 1985,
    "reziser": "Jiří Menzel"
  },
  {
    "id": 27,
    "nazev": "Interstellar",
    "rokVydani": 2014,
    "reziser": "Christopher Nolan"
  },
  {
    "id": 28,
    "nazev": "Gladiátor",
    "rokVydani": 2000,
    "reziser": "Ridley Scott"
  },
  {
    "id": 29,
    "nazev": "Lví král",
    "rokVydani": 1994,
    "reziser": "Roger Allers, Rob Minkoff"
  },
  {
    "id": 30,
    "nazev": "Dědictví aneb Kurvahošigutntag",
    "rokVydani": 1992,
    "reziser": "Věra Chytilová"
  }
]

3. Grafická nápověda

Logika aplikace

Po spuštění stránky se deklaruje proměnná seznamFilmu s výchozí hodnotou null a ihned se ověřuje její aktuální stav.

Pokud je proměnná prázdná (stav null), zobrazí se text o načítání a asynchronně se zavolá metoda GetFromJsonAsync(...). Stažená data se následně uloží do proměnné seznamFilmu. Tím dojde k novému vykreslení uživatelského rozhraní a systém se vrací zpět k ověření úvodní podmínky.

Při dalším průchodu již data existují. Aplikace proto přejde do cyklu, který testuje, zda v proměnné seznamFilmu zbývají nezpracované položky. Pro každý nalezený záznam se postupně vykreslí řádek v tabulce. Jakmile cyklus zpracuje všechny prvky, celá metoda končí.

4. Řešení úkolu

Třída Film
using System.Text.Json.Serialization;

namespace JSON_Filmy.Models
{
    public class Film
    {
        // Vlastnosti dodržují C# konvence a jsou namapovány na JSON klíče
        [JsonPropertyName("id")]
        public int Id { get; set; }

        [JsonPropertyName("nazev")]
        public string Nazev { get; set; }

        [JsonPropertyName("rokVydani")]
        public int RokVydani { get; set; }

        [JsonPropertyName("reziser")]
        public string Reziser { get; set; }
    }
}

V třídě Film definujeme základní datovou strukturu pro uchování informací o konkrétním snímku. Pro zajištění správné automatické deserializace z formátu JSON, při současném dodržení standardních jmenných konvencí jazyka C# je využit atribut [JsonPropertyName]. Tento atribut explicitně mapuje vlastnosti třídy v kódu na odpovídající textové klíče ve zdrojovém JSON souboru, které často začínají malým písmenem.


Razor komponenta
@page "/"
@inject HttpClient Http

<PageTitle>Moje filmy</PageTitle>

<h1>Seznam oblíbených filmů</h1>

@if (seznamFilmu == null)
{
    <p><em>Načítám data z JSON souboru...</em></p>
}
@else
{
    <table class="table table-striped">
        <thead>
            <tr>
                <th>Název filmu</th>
                <th>Rok vydání</th>
                <th>Režisér</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var film in seznamFilmu)
            {
                <tr>
                    <td><strong>@film.Nazev</strong></td>
                    <td>@film.RokVydani</td>
                    <td>@film.Reziser</td>
                </tr>
            }
        </tbody>
    </table>
}

@code {
    // Proměnná pro uložení načtených dat (pole filmů)
    private Models.Film[]? seznamFilmu;

    // Tato metoda se spustí automaticky při načtení stránky
    protected override async Task OnInitializedAsync()
    {
        // Cesta ukazuje do složky wwwroot/data
        seznamFilmu = await Http.GetFromJsonAsync<Models.Film[]>("data/filmy.json");
    }
}

Direktivou @inject vkládáme systémovou službu HttpClient, která komponentě zprostředkovává asynchronní síťovou komunikaci. V bloku @code deklarujeme privátní proměnnou seznamFilmu jako nullable pole (?), do kterého se v rámci životního cyklu komponenty přes přetíženou asynchronní metodu OnInitializedAsync nahrají data. Metoda GetFromJsonAsync<Models.Film[]> v jediném kroku stáhne textový soubor ze složky wwwroot a automaticky jej deserializuje do pole objektů. Uživatelské rozhraní následně reaguje pomocí podmínky @if – dokud je proměnná null (data se ještě stahují). Teprve po dokončení operace await se UI plynule přepne do větve else, kde pomocí cyklu @foreach vygeneruje pro každý jednotlivý objekt Film odpovídající řádek tabulky.