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ěď.
Poznáváme C# a Microsoft .NET – 68. díl – WebRequest a WebResponse

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, Síťový protokol, Díl, Zavolání

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

Jak se dostat do Windows, když neznáte heslo nebo nejste administrátor

Jak se dostat do Windows, když neznáte heslo nebo nejste administrátor

** S instalačním diskem Windows a znalostí pár příkazů odemknete téměř každý počítač s Windows. ** Poradíme i jak se tomu bránit

Včera | Tomáš Holčík | 34

Nový solární článek dokáže zachytit téměř veškerou energii světelného spektra ze Slunce

Nový solární článek dokáže zachytit téměř veškerou energii světelného spektra ze Slunce

** Vědci vytvořili nový typ solárního článku, který se pyšní neuvěřitelnou efektivitou ** Speciální trojrozměrná struktura dokáže zachytit téměř všechny vlnové délky světla ze Slunce ** Systém solárního článku využívá koncentrátorových čoček pro světlo

22.  7.  2017 | Karel Javůrek | 18

Další důkaz o existenci Planety 9

Další důkaz o existenci Planety 9

21.  7.  2017 | Jiří Černý | 5


Aktuální číslo časopisu Computer

Test 11 telefonů do 6 000 Kč

Postavte si a přetaktujte počítač

Srovnali jsme 7 sportovních kamer

Která zaměstnání nahradí roboti?