Sdílet prostřednictvím


Konfigurace webu, který používá aplikační služby (C#)

Scott Mitchell

Poznámka

Od napsání tohoto článku se zprostředkovatelé členství ASP.NET nahradili službou ASP.NET Identity. Důrazně doporučujeme aktualizovat aplikace tak, aby používaly platformu ASP.NET Identity Platform místo zprostředkovatelů členství, které se objevovalo v době psaní tohoto článku. ASP.NET Identity má oproti systému členství ASP.NET řadu výhod, mezi které patří:

  • Lepší výkon
  • Vylepšená rozšiřitelnost a testovatelnost
  • Podpora OAuth, OpenID Connect a dvojúrovňového ověřování
  • Podpora identit založených na deklarací identity
  • Lepší interoperabilita s ASP.Net Core

ASP.NET verze 2.0 zavedla řadu aplikačních služeb, které jsou součástí rozhraní .NET Framework a slouží jako sada služeb stavebních bloků, které můžete použít k přidání bohatých funkcí do webové aplikace. Tento kurz zkoumá, jak nakonfigurovat web v produkčním prostředí pro používání aplikačních služeb, a řeší běžné problémy se správou uživatelských účtů a rolí v produkčním prostředí.

Úvod

ASP.NET verzi 2.0 zavedli řadu aplikačních služeb, které jsou součástí rozhraní .NET Framework a slouží jako sada služeb stavebních bloků, které můžete použít k přidání bohatých funkcí do webové aplikace. Aplikační služby zahrnují:

  • Členství – rozhraní API pro vytváření a správu uživatelských účtů.
  • Role – rozhraní API pro kategorizaci uživatelů do skupin.
  • Profil – rozhraní API pro ukládání vlastního obsahu specifického pro uživatele.
  • Mapa webu – rozhraní API pro definování logické struktury webu ve formě hierarchie, která se pak dá zobrazit prostřednictvím navigačních ovládacích prvků, jako jsou nabídky a popis cesty.
  • Přizpůsobení – rozhraní API pro správu předvoleb přizpůsobení, které se nejčastěji používá s webovými částmi.
  • Monitorování stavu – rozhraní API pro monitorování výkonu, zabezpečení, chyb a dalších metrik stavu systému pro spuštěnou webovou aplikaci.

Rozhraní API aplikačních služeb nejsou svázaná s konkrétní implementací. Místo toho dáte aplikačním službám pokyn, aby používaly konkrétního poskytovatele, a tento poskytovatel službu implementuje pomocí konkrétní technologie. Nejčastěji používanými poskytovateli internetových webových aplikací hostovaných ve společnosti, která hostuje webhosting, jsou poskytovatelé, kteří používají SQL Server implementaci databáze. Například je poskytovatel rozhraní API pro členství, SqlMembershipProvider které ukládá informace o uživatelských účtech do databáze Microsoft SQL Server.

Používání aplikačních služeb a poskytovatelů SQL Server přináší při nasazování aplikace určité výzvy. Pro začátek musí být databázové objekty aplikačních služeb správně vytvořeny ve vývojové i produkční databázi a odpovídajícím způsobem inicializovány. Je také potřeba provést důležitá nastavení konfigurace.

Poznámka

Rozhraní API aplikačních služeb byla navržena pomocí modelu zprostředkovatele, vzoru návrhu, který umožňuje poskytovat podrobnosti o implementaci rozhraní API za běhu. Rozhraní .NET Framework se dodává s řadou poskytovatelů aplikačních služeb, které lze použít, například SqlMembershipProvider a SqlRoleProvider, což jsou poskytovatelé rozhraní API pro členství a role, která používají SQL Server implementaci databáze. Můžete také vytvořit vlastního poskytovatele a přidat ho do modulu plug-in. Webová aplikace Recenze knih už ve skutečnosti obsahuje vlastního zprostředkovatele pro rozhraní API mapy webu (ReviewSiteMapProvider), který vytváří mapu webu z dat v Genres tabulkách a Books v databázi.

Tento kurz začíná tím, že se podíváme na to, jak jsem webovou aplikaci Book Reviews rozšířil(a) tak, aby používala rozhraní API pro členství a role. Poté provede nasazením webové aplikace, která používá aplikační služby s implementací SQL Server databáze, a uzavře řešení běžných problémů se správou uživatelských účtů a rolí v produkčním prostředí.

Aktualizace do aplikace Recenze knih

Během posledních několika kurzů byla webová aplikace Recenze knih aktualizována ze statického webu na dynamickou daty řízenou webovou aplikaci, která obsahuje sadu stránek správy pro správu žánrů a recenzí. Tato část pro správu ale momentálně není chráněná – každý uživatel, který zná (nebo odhadne) adresu URL stránky správy, může na našem webu vytvářet, upravovat nebo odstraňovat recenze. Běžným způsobem, jak chránit určité části webu, je implementovat uživatelské účty a pak pomocí autorizačních pravidel adres URL omezit přístup na určité uživatele nebo role. Webová aplikace Recenze knih, která je k dispozici ke stažení v tomto kurzu, podporuje uživatelské účty a role. Má definovanou jednu roli s názvem Správa a pouze uživatelé v této roli mají přístup ke stránkám správy.

Poznámka

Ve webové aplikaci Recenze knih jsem vytvořil tři uživatelské účty: Scott, Jisun a Alice. Všichni tři uživatelé mají stejné heslo: heslo! Scott a Jisun jsou v Správa roli, Alice není. Stránky webu, které nejsou přístupné pro správu, jsou nadále přístupné anonymním uživatelům. To znamená, že se k návštěvě webu nemusíte přihlašovat, pokud ho nechcete spravovat. V takovém případě se musíte přihlásit jako uživatel v roli Správa.

Stránka předlohy aplikace Recenze knih byla aktualizována tak, aby obsahovala jiné uživatelské rozhraní pro ověřené a anonymní uživatele. Pokud web navštíví anonymní uživatel, uvidí v pravém horním rohu odkaz Přihlášení. Ověřený uživatel uvidí zprávu "Vítejte zpět, uživatelské jméno!" a odkaz pro odhlášení. K dispozici je také přihlašovací stránka (~/Login.aspx), která obsahuje ovládací prvek Přihlašovací web, který poskytuje uživatelské rozhraní a logiku pro ověřování návštěvníka. Nové účty můžou vytvářet jenom správci. (Ve složce jsou stránky pro vytváření a správu uživatelských ~/Admin účtů.)

Konfigurace rozhraní API pro členství a role

Webová aplikace Recenze knih používá rozhraní API pro členství a role k podpoře uživatelských účtů a k seskupení těchto uživatelů do rolí (konkrétně role Správa). Třídy SqlMembershipProvider zprostředkovatelů a SqlRoleProvider se používají, protože chceme ukládat informace o účtech a rolích do SQL Server databáze.

Poznámka

Tento kurz není určený k podrobnému zkoumání konfigurace webové aplikace pro podporu rozhraní API pro členství a role. Pokud se chcete důkladně podívat na tato rozhraní API a kroky, které je potřeba provést, abyste mohli nakonfigurovat web tak, aby je používal, přečtěte si moje kurzy zabezpečení webu.

Pokud chcete používat aplikační služby s databází SQL Server, musíte nejprve přidat databázové objekty používané těmito poskytovateli do databáze, do které chcete uložit informace o uživatelském účtu a roli. Tyto požadované databázové objekty zahrnují různé tabulky, zobrazení a uložené procedury. Pokud není uvedeno jinak, SqlMembershipProvider třídy zprostředkovatele a SqlRoleProvider používají databázi SQL Server Express Edition s názvem ASPNETDB umístěnou ve složce aplikaceApp_Data. Pokud taková databáze neexistuje, vytvoří se automaticky s potřebnými databázovými objekty těmito poskytovateli za běhu.

Je možné a obvykle ideální vytvořit databázové objekty aplikačních služeb ve stejné databázi, ve které jsou uložená data specifická pro aplikaci webu. Rozhraní .NET Framework se dodává s nástrojem s názvem aspnet_regsql.exe , který instaluje databázové objekty do zadané databáze. Pokračoval jsem a použil jsem tento nástroj k přidání těchto objektů do Reviews.mdf databáze ve App_Data složce (vývojová databáze). Způsob použití tohoto nástroje uvidíme později v tomto kurzu, až tyto objekty přidáme do produkční databáze.

Pokud přidáte databázové objekty aplikačních služeb do jiné databáze, než ASPNETDB budete muset přizpůsobit SqlMembershipProvider konfiguraci tříd zprostředkovatelů a SqlRoleProvider tak, aby používaly příslušnou databázi. Chcete-li přizpůsobit zprostředkovatele členství, přidejte <prvek členství> v oddílu <system.web> v Web.confignástroji ; pomocí elementu< roleManager> nakonfigurujte zprostředkovatele rolí. Následující fragment kódu pochází z aplikace Web.config Kontroly knih a ukazuje nastavení konfigurace pro rozhraní API pro členství a role. Všimněte si, že oba zaregistrují nového poskytovatele ( ReviewMembership a ReviewRole ), kteří používají SqlMembershipProvider poskytovatele a SqlRoleProvider (v uvedeném pořadí).

<configuration>
    <system.web>
        ...

        <membership defaultProvider="ReviewMembership">
            <providers>
                <clear />

                <add type="System.Web.Security.SqlMembershipProvider" 
                     name="ReviewMembership" 
                     connectionStringName="ReviewsConnectionString" 
                     applicationName="BookReviews" />
            </providers>
        </membership>

        <roleManager enabled="true" defaultProvider="ReviewRole">
            <providers>
                <clear />

                <add type="System.Web.Security.SqlRoleProvider" 
                     name="ReviewRole" 
                     connectionStringName="ReviewsConnectionString" 
                     applicationName="BookReviews" />
            </providers>
        </roleManager>

        ...
    </system.web>
</configuration>

Element Web.config file s <authentication> byl také nakonfigurován tak, aby podporoval ověřování na základě formulářů.

<configuration>
    <system.web>
        ...

        <authentication mode="Forms" />

        ...
    </system.web>
</configuration>

Omezení přístupu ke stránkám pro správu

ASP.NET usnadňuje udělení nebo odepření přístupu ke konkrétnímu souboru nebo složce uživatelem nebo rolí prostřednictvím funkce autorizace adres URL . (Stručně jsme probrali autorizaci adres URL v kurzu Základní rozdíly mezi službou IIS a ASP.NET Vývojový server a ukázali jsme si, jak služba IIS a vývojový server ASP.NET používají pravidla autorizace adres URL odlišně pro statický a dynamický obsah.) Vzhledem k tomu, že chceme zakázat přístup ke ~/Admin složce s výjimkou uživatelů v roli Správa, musíme do této složky přidat autorizační pravidla adresy URL. Konkrétně musí autorizační pravidla adres URL povolit uživatele v Správa roli a odepřít všechny ostatní uživatele. Toho dosáhnete přidáním Web.config souboru do ~/Admin složky s následujícím obsahem:

<?xml version="1.0"?>
<configuration>
    <system.web>
        <authorization>
            <allow roles="Admin" />
            <deny users="*" />
        </authorization>
    </system.web>
</configuration>

Další informace o funkci autorizace adres URL ASP.NET a o tom, jak ji používat k vypsání autorizačních pravidel pro uživatele a role, si nezapomeňte přečíst kurzy autorizace na základě uživatele a autorizace na základě rolí v mých kurzech zabezpečení webu.

Nasazení webové aplikace, která používá aplikační služby

Při nasazování webu, který používá aplikační služby, a poskytovatele, který ukládá informace o aplikačních službách v databázi, je nutné, aby databázové objekty potřebné aplikačními službami byly vytvořeny v produkční databázi. Produkční databáze zpočátku tyto objekty neobsahuje, takže při prvním nasazení aplikace (nebo při prvním nasazení po přidání aplikačních služeb) je nutné provést dodatečné kroky k získání těchto požadovaných databázových objektů do produkční databáze.

Další problém může nastat při nasazení webu, který používá aplikační služby, pokud chcete replikovat uživatelské účty vytvořené ve vývojovém prostředí do produkčního prostředí. V závislosti na konfiguraci členství a rolí je možné, že i když úspěšně zkopírujete uživatelské účty vytvořené ve vývojovém prostředí do produkční databáze, tito uživatelé se nemůžou přihlásit k webové aplikaci v produkčním prostředí. Podíváme se na příčinu tohoto problému a probereme, jak tomu zabránit.

ASP.NET se dodává s pěkným nástrojem pro správu webu (WSAT), který lze spustit ze sady Visual Studio a umožňuje správu uživatelských účtů, rolí a autorizačních pravidel prostřednictvím webového rozhraní. WsAT bohužel funguje pouze pro místní weby, což znamená, že ho nelze použít ke vzdálené správě uživatelských účtů, rolí a autorizačních pravidel pro webovou aplikaci v produkčním prostředí. Podíváme se na různé způsoby implementace chování podobného WSAT z vašeho produkčního webu.

Přidání databázových objektů pomocí aspnet_regsql.exe

Kurz Nasazení databáze ukázal, jak zkopírovat tabulky a data z vývojové databáze do produkční databáze. Tyto techniky se dají určitě použít ke zkopírování databázových objektů aplikačních služeb do produkční databáze. Další možností je aspnet_regsql.exe nástroj, který přidá nebo odebere databázové objekty aplikačních služeb z databáze.

Poznámka

Nástroj aspnet_regsql.exe vytvoří databázové objekty v zadané databázi. Nemigruje data v těchto databázových objektech z vývojové databáze do produkční databáze. Pokud chcete zkopírovat informace o uživatelském účtu a roli ve vývojové databázi do produkční databáze, použijte techniky popsané v kurzu Nasazení databáze .

Pojďme se podívat, jak přidat databázové objekty do produkční databáze pomocí nástroje aspnet_regsql.exe . Začněte tím, že otevřete Průzkumníka Windows a přejdete do adresáře .NET Framework verze 2.0 v počítači % WINDIR%\ Microsoft.NET\Framework\v2.0.50727. Tam byste měli aspnet_regsql.exe najít nástroj. Tento nástroj lze použít z příkazového řádku, ale obsahuje také grafické uživatelské rozhraní; poklikáním na aspnet_regsql.exe soubor spusťte jeho grafickou komponentu.

Nástroj začne zobrazením úvodní obrazovky s vysvětlením svého účelu. Kliknutím na Další přejděte na obrazovku Vybrat možnost nastavení, která je znázorněna na obrázku 1. Tady můžete přidat databázové objekty aplikačních služeb nebo je z databáze odebrat. Protože chceme tyto objekty přidat do produkční databáze, vyberte možnost Konfigurovat SQL Server pro aplikační služby a klikněte na Další.

Volba konfigurace SQL Server pro aplikační služby

Obrázek 1: Volba konfigurace SQL Server pro aplikační služby (kliknutím zobrazíte obrázek v plné velikosti)

Na obrazovce Vybrat server a databázi se zobrazí výzva k zadání informací pro připojení k databázi. Zadejte databázový server, přihlašovací údaje zabezpečení a název databáze, který vám poskytla vaše společnost pro hostování webů, a klikněte na Další.

Poznámka

Po zadání databázového serveru a přihlašovacích údajů může dojít k chybě při rozbalování rozevíracího seznamu databáze. Nástroj aspnet_regsql.exe se dotazuje sysdatabases na systémovou tabulku, aby načetl seznam databází na serveru, ale některé společnosti hostující web zamknou své databázové servery, aby tyto informace nebyly veřejně dostupné. Pokud se zobrazí tato chyba, můžete zadat název databáze přímo do rozevíracího seznamu.

Zadejte nástroj s informacemi o připojení k databázi.

Obrázek 2: Zadejte nástroj s informacemi o připojení k databázi (kliknutím zobrazíte obrázek v plné velikosti)

Následující obrazovka shrnuje akce, které se mají provést, konkrétně to, že databázové objekty aplikačních služeb budou přidány do zadané databáze. Kliknutím na Další tuto akci dokončete. Po chvíli se zobrazí poslední obrazovka s upozorněním, že byly přidány databázové objekty (viz obrázek 3).

Úspěch! Databázové objekty aplikačních služeb byly přidány do produkční databáze.

Obrázek 3: Úspěch! Databázové objekty aplikačních služeb byly přidány do produkční databáze (kliknutím zobrazíte image v plné velikosti).

Pokud chcete ověřit, že se databázové objekty aplikačních služeb úspěšně přidaly do produkční databáze, otevřete SQL Server Management Studio a připojte se k produkční databázi. Jak ukazuje obrázek 4, v databázi byste teď měli vidět databázové tabulky aplikačních služeb, aspnet_Applicationsaspnet_Membershipaspnet_Users, a tak dále.

Potvrďte, že se databázové objekty přidaly do produkční databáze.

Obrázek 4: Potvrďte, že se databázové objekty přidaly do produkční databáze (kliknutím zobrazíte obrázek v plné velikosti)

Nástroj budete muset použít aspnet_regsql.exe pouze při prvním nasazení webové aplikace nebo poprvé po zahájení používání aplikačních služeb. Jakmile jsou tyto databázové objekty v produkční databázi, nebude je nutné znovu přidávat ani upravovat.

Kopírování uživatelských účtů z vývoje do produkčního prostředí

Při použití SqlMembershipProvider tříd a SqlRoleProvider zprostředkovatele k ukládání informací o aplikačních službách v databázi SQL Server jsou informace o uživatelských účtech a rolích uloženy v různých databázových tabulkách, mezi aspnet_Membershipaspnet_Usersaspnet_Roleskteré patří , a .aspnet_UsersInRoles Pokud během vývoje vytvoříte uživatelské účty ve vývojovém prostředí, můžete tyto uživatelské účty replikovat v produkčním prostředí zkopírováním odpovídajících záznamů z příslušných databázových tabulek. Pokud jste k nasazení databázových objektů aplikačních služeb použili Průvodce publikováním databáze, možná jste se také rozhodli záznamy zkopírovat, což by vedlo k tomu, že uživatelské účty vytvořené při vývoji budou také v produkčním prostředí. V závislosti na nastavení konfigurace ale můžete zjistit, že uživatelé, jejichž účty byly vytvořeny ve vývoji a zkopírovány do produkčního prostředí, se z produkčního webu nemůžou přihlásit. Co dává?

Třídy SqlMembershipProvider poskytovatelů a SqlRoleProvider byly navrženy tak, aby jedna databáze mohla sloužit jako úložiště uživatelů pro více aplikací, kde by teoreticky každá aplikace mohla mít uživatele s překrývajícími se uživatelskými jmény a rolemi se stejným názvem. Pro zajištění této flexibility databáze udržuje seznam aplikací v aspnet_Applications tabulce a každý uživatel je přidružený k jedné z těchto aplikací. Konkrétně tabulka obsahuje sloupec, aspnet_Users který spojuje každého uživatele se záznamem v tabulceaspnet_Applications.ApplicationId

Kromě ApplicationId sloupce aspnet_Applications obsahuje ApplicationName tabulka také sloupec, který pro aplikaci poskytuje lidsky přívětivější název. Když se web pokusí pracovat s uživatelským účtem, například ověření přihlašovacích údajů uživatele z přihlašovací stránky, musí třídě sdělit SqlMembershipProvider , s jakou aplikací má pracovat. Obvykle to dělá tak, že zadá název aplikace a tato hodnota pochází z konfigurace zprostředkovatele v Web.config – konkrétně prostřednictvím atributu applicationName .

Co se ale stane, applicationName když atribut není zadán v Web.config? V takovém případě systém členství použije jako applicationName hodnotu kořenovou cestu aplikace. applicationName Pokud atribut není explicitně nastaven v Web.config, pak existuje možnost, že vývojové prostředí a produkční prostředí používají jiný kořen aplikace, a proto budou přidruženy k různým názvům aplikací v aplikačních službách. Pokud k takové neshodě dojde, budou mít tito uživatelé vytvořené ve vývojovém ApplicationId prostředí hodnotu, která neodpovídá hodnotě ApplicationId produkčního prostředí. Výsledkem je, že se tito uživatelé nebudou moct přihlásit.

Poznámka

Pokud se v této situaci nacházíte s uživatelskými účty zkopírovanými do produkčního prostředí s neodpovídající ApplicationId hodnotou, můžete napsat dotaz, který aktualizuje tyto nesprávné ApplicationId hodnoty na ApplicationId použité v produkčním prostředí. Po aktualizaci se teď uživatelé, jejichž účty byly vytvořené ve vývojovém prostředí, budou moct přihlásit k webové aplikaci v produkčním prostředí.

Dobrou zprávou je, že existuje jednoduchý krok, kterým můžete zajistit, aby obě prostředí používala stejné ApplicationId – explicitně nastavte applicationName atribut pro Web.config všechny poskytovatele služeb aplikací. Explicitně jsem atribut nastavil applicationName na "BookReviews" v <membership> elementech a <roleManager> , jak ukazuje tento fragment kódu z Web.config .

<membership defaultProvider="ReviewMembership">
    <providers>
        <clear />

        <add type="System.Web.Security.SqlMembershipProvider" 
             name="ReviewMembership" 
             connectionStringName="ReviewsConnectionString" 
             applicationName="BookReviews" />
    </providers>
</membership>

Další informace o nastavení atributu applicationName a jeho důvodech najdete v blogovém příspěvku Scotta GuthriehoVždy nastavte vlastnost applicationName při konfiguraci členství ASP.NET a dalších poskytovatelů.

Správa uživatelských účtů v produkčním prostředí

Nástroj ASP.NET Web Site Administration Tool (WSAT) usnadňuje vytváření a správu uživatelských účtů, definování a používání rolí a vytváření autorizačních pravidel založených na uživatelích a rolích. WsAT můžete spustit ze sady Visual Studio tak, že přejdete na Průzkumník řešení a kliknete na ikonu konfigurace ASP.NET nebo přejdete do nabídky Web nebo Projekt a vyberete položku nabídky Konfigurace ASP.NET. WSAT bohužel může pracovat pouze s místními weby. Proto nelze použít WSAT z pracovní stanice ke správě webu v produkčním prostředí.

Dobrou zprávou je, že všechny funkce zpřístupněné WSAT jsou k dispozici prostřednictvím kódu programu prostřednictvím rozhraní API pro členství a role. Mnoho obrazovek WSAT navíc používá standardní ovládací prvky související s přihlášením ASP.NET. Stručně řečeno, můžete na web přidat ASP.NET stránky, které nabízejí potřebné možnosti správy.

Vzpomeňte si, že předchozí kurz aktualizoval webovou aplikaci Book Reviews tak, aby obsahovala ~/Admin složku, a tato složka byla nakonfigurována tak, aby povolovala pouze uživatele v roli Správa. Přidal(a) jsem do této složky stránku s názvem CreateAccount.aspx , ze které může správce vytvořit nový uživatelský účet. Tato stránka používá ovládací prvek CreateUserWizard k zobrazení uživatelského rozhraní a back-endové logiky pro vytvoření nového uživatelského účtu. Navíc jsem ovládací prvek přizpůsobil(a) tak, aby obsahoval zaškrtávací políčko s výzvou, zda má být nový uživatel také přidán do role Správa (viz obrázek 5). S trochou práce můžete vytvořit vlastní sadu stránek, která implementuje úlohy související se správou uživatelů a rolí, které by jinak poskytoval WSAT.

Poznámka

Další informace o používání rozhraní API pro členství a role spolu s webovými ovládacími prvky souvisejícími s přihlášením ASP.NET najdete v kurzech zabezpečení webu. Další informace o přizpůsobení ovládacího prvku CreateUserWizard najdete v kurzech Vytváření uživatelských účtů a Ukládání dalších informací o uživatelích nebo si přečtěte článek Přizpůsobení ovládacího prvku CreateUserWizardErich Peterson.

Správci můžou vytvářet nové uživatelské účty

Obrázek 5: Správci můžou vytvářet nové uživatelské účty (kliknutím zobrazíte obrázek v plné velikosti)

Pokud potřebujete plnou funkčnost WSAT, podívejte se na nástroj Pro správu vlastního webu, ve kterém autor Dan Clem provede procesem vytvoření vlastního nástroje podobného WSAT. Dan sdílí zdrojový kód aplikace (v jazyce C#) a poskytuje podrobné pokyny pro jeho přidání na hostovaný web.

Souhrn

Při nasazování webové aplikace, která používá implementaci databáze aplikačních služeb, musíte nejprve zajistit, aby produkční databáze obsahuje požadované databázové objekty. Tyto objekty lze přidat pomocí technik probíraných v kurzu Nasazení databáze ; Případně můžete použít aspnet_regsql.exe nástroj, jak jsme viděli v tomto kurzu. Další problémy, kterých jsme se dotkli, se soustředí na synchronizaci názvu aplikace používaného ve vývojovém a produkčním prostředí (což je důležité, pokud chcete, aby uživatelé a role vytvořené ve vývojovém prostředí byly platné v produkčním prostředí) a techniky pro správu uživatelů a rolí v produkčním prostředí.

Šťastné programování!

Další čtení

Další informace o tématech probíraných v tomto kurzu najdete v následujících zdrojích informací: