Poznáváme C# a Microsoft .NET – 68. díl – WebRequest a WebResponse

Náš zájem je dnes stejně jako v díle předchozím zamířen na aplikace pracující v síti. Dnes se ale podíváme na to jakým způsobem je možné na platformě .NET implementovat síťové aplikace, využívající architekturu požadavek/odpověď.

Architektura požadavek/odpověď v .NET

I přestože je přístup k síťovým zdrojům pomocí třídy WebClient, kterou jsme si představovali v minulém díle, velmi jednoduchý, často při implementaci síťových aplikací narazíme na situace, kde pro nás bude její vysoká míra abstrakce omezující. V takovýchto případech „sáhneme“ po dvojici tříd WebRequest a WebResponse ze jmenného prostoru System.Net. Tyto třídy pro nás představují cestu k implementaci aplikací na základě přístupu požadavek/odpověď, kde je na základě URI proveden požadavek na vzdálený zdroj a ten je nám, pokud vše dobře zafunguje, v podobě odpovědi navrácen.

Implementace zmíněného přístupu pomocí tříd WebRequest a WebResponse je založen na principu datových proudů a využívání abstraktních tříd či rozhraní. Obě uvedené třídy jsou třídami abstraktními, tudíž není možné vytvořit jejich instance a jsou jen obecnými bázovými třídami, z nichž jsou odvozeny implementace pro konkrétní síťové protokoly. Cestou k vytvoření objektu představující požadavek na konkrétní vzdálený zdroj je použití statické tovární metody Create třídy WebRequest .

Po tomto vytvoření jsme schopni na vzniklém objektu pomocí jeho metody získat objekt představující odpověď. Pokud v naší aplikaci nepotřebujeme využívat vlastností jednotlivých protokolů (např. HTTP) můžeme pracovat pouze s rozhraním tříd WebRequest a WebResponse a tím tedy pracovat pouze na obecné úrovní požadavek/odpověď. Standardně jsou v .NET frameworku verze 1.1 implementovány třídy ovladačů pro protokoly HTTP, HTTPS a FILE. V .NET frameworku verze 2.0 ještě přibyla podpora pro protokol FTP.

Jak by mohl vypadat jednoduchý příklad, který pro přístup ke vzdálenému zdroji využívá tříd WebRequest a WebResponse ukazuje následující příklad.

//nacteni URI, na ktery bude proveden pozadavek
Console.Write("Zadejte URI (napr.
) : ");
string uri = Console.ReadLine();
//vytvoreni instance pozadavku
WebRequest  request = WebRequest .Create(uri);
WebResponse response = null;
StreamReader reader = null;
try
{
  //vyslani pozadavku a ziskani odpovedi
  response = request.GetResponse();
  //ziskani datoveho proudu odpovedi
  Stream strm = response.GetResponseStream();
  reader = new StreamReader(strm);
  //nacteni textu odpovedi
  string content = reader.ReadToEnd();
  Console.WriteLine(content);
}
catch(WebException ex)
{
  Console.WriteLine("Doslo k vyjimce : {0}", ex.ToString());
}
finally
{
  if (reader != null)
  {
    reader.Close();
  }
  if (response != null)
  {
    response.Close();
  }

}

Tovární metoda Create na základě identifikátoru protokolu v URI vrací objekt požadavku pro daný protokol, ke kterému je standardně přistupováno přes rozhraní abstraktní třídy WebRequest . Vytvořením objektu požadavku není ještě skutečný síťový požadavek odeslán. Děje se tomu až v čase získávání objektu odpovědi, což učiníme zavoláním metody GetResponse na objektu požadavku. Pro získání datového proudu obdržené odpovědi využijeme metodu GetResponseStream a následně jej nějakým způsobem zpracujeme. Po tom co získanou odpověď zpracujeme, tak nikdy nesmíme zapomenout na uzavření spojení, což zařídíme metodou Close na objektu odpovědi.

Specifické vlastnosti protokolu HTTP

Z důvodu zachování určité míry abstrakce se často pracuje pouze na úrovní použití rozhraní základních tříd WebRequest a WebResponse. Metoda Create vrací odkaz na obecný typ požadavku WebRequest a metoda GetResponse zase na obecný typ odpovědi WebResponse. Tím je dosažena nezávislost na síťovém protokolu ve zdrojovém kódu.

To jací specifičtí potomci tříd WebRequest a WebResponse jsou ve skutečnosti používány je závislé pouze na použitém URI, který je předán metodě Create. Ve skutečnosti tovární metoda Create v případě, že je jako identifikátor protokolu v URI uvedeno http://, vrátí instanci třídy HttpWebRequest a metoda GetResponse vrací instanci třídy HttpWebResponse.

V případě použití identifikátoru protokolu file:// jsou zase vráceny specializované instance FileWebRequest a FileWebResponse. Takže pokud chceme využít specifické vlastnosti protokolu HTTP, využijeme těchto specializovaných potomků. Toho jednoduše docílíme pomocí přetypování směrem dolů, jak ukazuje následující příklad.

//nacteni URI, na ktery bude proveden pozadavek
Console.Write("Zadejte adresu pro HTTP pozadavek (napr.
www.zive.cz) : ");
string uri = "http://" + Console.ReadLine();
//vytvoreni instance pozadavku
HttpWebRequest  request = (HttpWebRequest ) WebRequest .Create(uri);
//nastaveni specificke vlastnosti HTTP pozadavku
request.UserAgent = "Pokusny klient";
HttpWebResponse response = null;
try
{
  response = (HttpWebResponse)request.GetResponse();
  //precteni specifickych vlastnosti HTTP odpovedi
  Console.WriteLine("Last modified : {0}", response.LastModified);
  Console.WriteLine("Status code : {0}", response.StatusCode);
}
finally
{
  if (response != null)
  {
    response.Close();
  }
}

Tím, že jsme provedli přetypování na specializované implementace tříd WebRequest /WebResponse jsme získali možnost pomocí jejich instančních vlastností specifikovat (v případě požadavku) a číst (v případě odpovědi) specifické informace obsažené v záhlaví. Takže v ukázkovém zdrojovém kódu jsme například požadavku nastavili vlastnost USER AGENT sloužící k podání informací o použitém prohlížeči a z objektu odpovědi jsme přečetli datum poslední modifikace a kód stavu.

K záhlaví požadavku čí odpovědi lze přistupovat i na obecné úrovni tříd WebRequest a WebResponse a to pomocí jejich instanční vlastnosti Headers, která je typu kolekce WebHeaderCollection. Pomocí prvků této kolekce jsme schopni přistupovat i k těm informací v záhlaví, které nejsou k dispozici pomocí API na specializovaných potomcích. Samozřejmě vlastnost Headers můžete využít nejen u obecných tříd WebRequest a WebResponse, ale i u jejich odvozených tříd (např. HttpWebRequest ).

//nacteni URI, na ktery bude proveden pozadavek
Console.Write("Zadejte URI (napr.
) : ");
string uri = Console.ReadLine();
//vytvoreni instance pozadavku
WebRequest  request = WebRequest .Create(uri);
WebResponse response = null;
try
{
  //vyslani pozadavku a ziskani odpovedi
  response = request.GetResponse();
  for (int i = 0; i < response.Headers.Count; i++)
  {
    string headerKey = response.Headers.GetKey(i);
    string headerValue = response.Headers[i];
    Console.WriteLine("{0} - {1}", headerKey, headerValue);
  }
}
catch(WebException ex)
{
  Console.WriteLine("Doslo k vyjimce : {0}", ex.ToString());
}
finally
{
  if (response != null)
  {
    response.Close();
  }
}

Zdrojové kódy příkladů ke článku jsou ke stažení zde.

Témata článku: Software, Microsoft, Programování, Catch

1 komentář

Nejnovější komentáře

  • gully, gully 27. 6. 2006 23:51:53
    Off-line verzi seriálu si můžete stáhnout z...
Určitě si přečtěte

Špičkoví hackeři útočili na prohlížeče. Chrome odolal, ale Edge je tragédie

Špičkoví hackeři útočili na prohlížeče. Chrome odolal, ale Edge je tragédie

** Do Vancouveru se sjeli hackeři ** Soutěžili v útocích na prohlížeče ** Chrome odolal, ale Edge to projel na celé čáře

22.  3.  2017 | Jakub Čížek | 79

Obří Mechroboti jsou realitou, měří čtyři metry a mají hmotnost přes 1,5 tuny

Obří Mechroboti jsou realitou, měří čtyři metry a mají hmotnost přes 1,5 tuny

** Jihokorejská společnost Hankook Mirae Technology vyrábí obří Mechroboty ** Jsou určené pro ovládání člověkem uvnitř ** V prodeji se objeví koncem tohoto roku za 200 milionů korun

20.  3.  2017 | Karel Javůrek | 18

Nebuďte jako Emma Watson. Poradíme, jak nepřijít o hanbaté fotky

Nebuďte jako Emma Watson. Poradíme, jak nepřijít o hanbaté fotky

** Pokud už choulostivé snímky vyfotíte, dbejte na jejich zabezpečení ** Útočníci je nejčastěji získají z cloudového úložiště ** Pozor si dejte i na phishing a řádné zabezpečení telefonu

Včera | Stanislav Janů | 32

Google představil nový Android O. Na co se můžeme těšit?

Google představil nový Android O. Na co se můžeme těšit?

** Google vypustil vývojářskou verzi nového Androidu ** Přinese lepší notifikace nebo prodlouženou výdrž ** K uživatelům se dostane na podzim

22.  3.  2017 | Stanislav Janů | 60


Aktuální číslo časopisu Computer

Supertéma o počítačové bezpečnosti

AMD Ryzen přichází

Velké testy kinoprojektorů a levných sluchátek

Příslušenství do USB-C