reklama

Poznáváme C# a Microsoft .NET - 69. díl – Pokročilé využití tříd WebRequest a WebResponse

Třídy WebRequest a WebResponse a jejich využití již po minulém dílu známe a dnes se zaměříme na jejich použití v pokročilejších scénářích, kterými jsou realizace asynchronních požadavků, posílání dat a autentizace.

Asynchronní požadavky

Jistě některé z vás při čtení minulého dílu, který pojednával o získávání vzdálených dat pomocí tříd WebRequest a WebResponse, že by bylo užitečné mít možnost učinit požadavek na vzdálený zdroj asynchronně, tedy ve vlastním vlákně. To se hodí například v případech, kdy se vzdálený zdroj, na který zasíláme požadavek nachází na serveru, jenž je značně zatěžován a tudíž získání odpovědi může být otázka i několika vteřin. Po tuto dobu můžeme chtít nechat naši aplikaci vykonávat další operace a v době získání odpovědi na náš zaslaný požadavek na tuto událost zareagovat příslušnými akcemi.

Pro dosažení tohoto cíle můžeme směle využít metody BeginGetResponse na instanci třídy WebRequest v kombinaci s užitím instance delegáta AsyncCallBack jak ukazuje následující příklad.

/// <summary>
/// Ukazka pouziti tridy WebRequest k realizaci asynchronniho pozadavku
/// </summary>
public class AsyncRequest
{
 public static void Run()
 {
  //nacteni URI, na ktery bude proveden pozadavek
  Console.Write("Zadejte URI (napr.
) : ");
  string uri = Console.ReadLine();
  //vytvoreni instance pozadavku
  WebRequest request = WebRequest.Create(uri);
  try
  {
   AsyncCallback callback = new AsyncCallback(ResponseCallBack);
   //zahajeni asynchronniho vyslani pozadavku
   request.BeginGetResponse(callback, request);
  }
  catch(Exception ex)
  {
   Console.WriteLine("Nastala vyjimka {0}", ex.ToString());
  }
  //cekani na dokonceni asynchronni operace
  Console.ReadLine();
 }

 //obsluzna metoda pro zpracovani asynchronniho pozadavku
 static void ResponseCallBack(IAsyncResult result)
 {
  //ziskani objektu pozadavku, ktery je zpracovavan
  WebRequest request = (WebRequest) result.AsyncState;
  StreamReader reader = null;
  WebResponse response = null;
  if (result.IsCompleted)
  {
   try
   {
    //ukonceni vlakna provadejiciho pozadavek a ziskani vysledku
    response = request.EndGetResponse(result);
    //ziskani datoveho proudu odpovedi
    Stream responseStream = response.GetResponseStream();
    //vypsani vysledku
    reader = new StreamReader(responseStream);
    string content = reader.ReadToEnd();
    Console.WriteLine(content);
   }
   catch(Exception ex)
   {
    Console.WriteLine("Nastala vyjimka {0}", ex.ToString());
   }
   finally
   {
    if (reader != null)
    {
     reader.Close();
    }
    if (response != null)
    {
     response.Close();
    }
   }
  }
 }
}

Zpracování odpovědi je v tomto asynchronním scénáři stejné jako v případě využití asynchronních delegátů, tedy reakcí na dokončení operace pomocí instance delegáta AsyncCallBack. Tuto instanci předáme jako parametr metodě BeginGetResponse a jako druhý parametr předáme objekt, který si po té můžeme v obslužné metodě vyzvednout. V přikladu je předán přímo objekt WebRequest, který je následně v obslužné metodě ResponseCallBack pomocí vlastnosti AsyncState vyzvednut. Pomocí objektu WebRequest je získán objekt WebResponse, představující odpověď, zavoláním metody EndGetResponse, která ukončí provádění asynchronního požadavku. Po té již standardním způsobem přečteme obsah odpovědi.

Zasílání dat

S poměrně velkou pravděpodobností se při implementaci aplikací získávající internetové zdroje dostanete do situace, kdy bude zapotřebí zaslat danému zdroji nějaká data, která budou na vzdáleném serveru zpracována a na jejichž základě vám bude vrácena odpověď. V případě, že budeme využívat protokolu HTTP, tak dvěma hlavními metodami, kterými jsme schopni zmíněná data předat jsou metody GET a POST. Využití metody GET je jednoduché, protože názvy parametrů a jejich hodnoty jsou přímo části URI. Naproti metoda POST využívá hlavičky požadavku a této metody je užito například při odesílání dat z webových formulářů.

To jakou metodu pro poslání dat použijeme jsme schopni při použití třídy WebRequest definovat pomocí její instanční vlastnosti Method. Pro získání datového proudu požadavku, jimž budeme data zasílat použijeme metodu GetRequestStream. Důležité je také nastavit typ zasílaných dat a také jejich velikost, což zajistíme pomocí vlastností ContentType a ContentLength.
Jako inspirace může posloužit následující zdrojový kód.

//nacteni URI
Console.Write("Zadejte URI na kterou budou poslana data : ");
string uri = Console.ReadLine();
//nacteni dat k odeslani
Console.Write("Zadejte data, ktera budou s pozadavkem poslana : ");
string data = Console.ReadLine();
Stream requestStream = null;
Stream responseStream = null;
try
{
 //vytvoreni objektu pozadavku
 WebRequest request = WebRequest.Create(uri);
 //nastaveni metody odeslani dat
 request.Method = "POST";
 //nastaveni velikosti posilanych dat v bajtech
 request.ContentLength = System.Text.Encoding.Default.GetByteCount(data);
 //nastaveni typu obsahu
 request.ContentType = "application/x-www-form-urlencoded";
 //zapsani dat do proudu pozadavku
 requestStream = request.GetRequestStream();
 StreamWriter writer = new StreamWriter(requestStream);
 writer.Write(data);
 writer.Close();
 //ziskani obsahu odpovedi
 responseStream = request.GetResponse().GetResponseStream();
 StreamReader reader = new StreamReader(responseStream);
 string received = reader.ReadToEnd();
 Console.WriteLine(received);
}
catch(Exception ex)
{
 Console.WriteLine("Nastala vyjimka : {0}", ex.ToString());
}
finally
{
 if (requestStream != null)
 {
  requestStream.Close();
 }
 if (responseStream != null)
 {
  responseStream.Close();
 }
}

Všimněte si, že jako typ obsahu je pomocí vlastnosti ContentType nastavena hodnota application/x-www-form-urlencoded, což je hodnota, které je užíváno při zmíněném odesílání formulářových aplikací. Takže stránka na kterou bude vznášen náš požadavek bude moci tato data vyzvednout stejným způsobem jako když přijímá data z odeslaného webového formuláře (tedy pokud bude řetězec představující data ve správném formátu název=hodnota).

Poznámka: Pro možnost vyzkoušení tohoto příkladu je v příkladech ke stažení také jednoduchá ASP .NET stránka, která umí touto formou zaslaná data zpracovat.

Požadavky na zabezpečené zdroje

Ne ke všem zdrojům v síti je možné přistupovat anonymně. Některé webové aplikace vyžadují, aby s sebou požadavky, které na ni směřují nesly informaci o uživateli, který tyto požadavky zasílá. Tyto aplikace pak na základě těchto předaných dat rozhodnou, jestli požadavek na konkrétní zdroj bude autorizován či nikoli.

Samozřejmě i na toto je v .NET frameworku myšleno a objektu WebRequest je možné nastavit výše zmíněné autentikační údaje pomocí vlastnosti Credentials.

Console.Write("Zadejte URI : ");
string uri = Console.ReadLine();
WebRequest request = WebRequest.Create(uri);
Console.Write("Zadejte uzivatele : ");
string user = Console.ReadLine();
Console.Write("Zadejte heslo: ");
string password = Console.ReadLine();
//vytvoreni objektu nesouciho autentikacni udaje
NetworkCredential credential = new NetworkCredential(user, password);
//prirazeni autentikacniho objektu k pozadavku
request.Credentials = credential;
Stream responseStream = null;
try
{
 responseStream = request.GetResponse().GetResponseStream();
 StreamReader reader = new StreamReader(responseStream);
 Console.WriteLine(reader.ReadToEnd());
}
catch(WebException ex)
{
 HttpWebResponse response = (HttpWebResponse) ex.Response;
 if (response.StatusCode == HttpStatusCode.Unauthorized)
 {
  Console.WriteLine("Pristup byl odepren !");
 }
 else
 {
  throw;
 }
  
}
finally
{
 if (responseStream != null)
 {
  responseStream.Close();
 }
}

Zmíněná vlastnost Credentials je typu rozhraní ICredentials a implementací použitou v tomto příkladu je třída NetworkCredential. Při vytváření instance této třídy předáme konstruktoru autentikační údaje, kterými jsou jméno a heslo uživatele. V případě, že se žádost o vzdálený zdroj nezdaří, jsme schopni zjistit, jestli je to z důvodu neudělení autorizace. Výjimka WebException, která je v případě vzniku chyby při provádění požadavku vyhozena, umožňuje získat odkaz na objekt WebResponse po jehož přetypování na HttpWebResponse (pokud tedy používáme k přístupu protokol HTTP) je možné zjistit z jakého důvodu chyba vznikla přečtením stavového kódu odpovědi (vlastnost StatusCode).

Existuje i možnost jak spolu s požadavkem zaslat autentikační údaje uživatele pod jehož kontextem daná aplikace běží (uživatel, který spustil aplikaci). Za účelem získání takovéhoto objektu ICredentials využijeme třídy CredentialCache, jejímž hlavním účelem je uchovávat autentikační údaje pro různé vzdálené zdroje, a její vlastnosti DefaultCredential.

//k autentikaci pouzijeme ucet uzivatele pod nimz bezi tato aplikace
request.Credentials = CredentialCache.DefaultCredentials;

Poznámka: ASP .NET aplikace, která je dodávána spolu s příklady je nakonfigurována tak, že odmítá požadavky od neautorizovaných zdrojů (nastaveno v souboru web.config), tudíž si můžete vyzkoušet, že pokud s požadavkem nezašlete údaje o uživateli váš požadavek bude odmítnut.

Příklady ke článku jsou ke stažení zde.

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

3 komentáře

Nejnovější komentáře

  • Pavel Polívka 24. 11. 2007 13:57:03
    Programovou oflline verzi seriálu naleznete ke stažení na...
  • Johnny 19. 4. 2006 19:38:21
    Je to fakt super, nemuzu si stezovat...
    http://www.make4u.cz
  • Svatopluk 17. 4. 2006 8:38:39
    chtěl bych taky do dělat web stranky
reklama
Určitě si přečtěte

Facebook o nás ví vše. Díky dobře skrytému vyhledávači se to dozví i ostatní

Facebook o nás ví vše. Díky dobře skrytému vyhledávači se to dozví i ostatní

** Facebook o nás ví vše, protože mu to sami řekneme ** V jeho nitru se skrývá mocný vyhledávač ** Mohou jej zneužít stalkeři, sociální inženýři a další nezbedníci

16.  2.  2017 | Jakub Čížek | 76

Pojďme programovat elektroniku: Žádný bastlíř se neobejde bez armády švábů

Pojďme programovat elektroniku: Žádný bastlíř se neobejde bez armády švábů

** Každý bastlíř se po čase neobjede bez armády švábů ** Dnes si některé z nich vyzkoušíme ** Třeba zázračný posuvný registr

19.  2.  2017 | Jakub Čížek | 36

K čemu jsou v zimě dobré chytré hodinky? Z lyžování vám udělají datové orgie

K čemu jsou v zimě dobré chytré hodinky? Z lyžování vám udělají datové orgie

** Chytré hodinky našly uplatnění především ve sportu ** Běhání či jízdu na kole zvládnou všechny, ale co třeba lyžování? ** Podívejte se, jak jsou na zimní sporty připraveny hodinky Garmin Fenix 3

15.  2.  2017 | David Polesný | 22


Aktuální číslo časopisu Computer

Stavba 3D tiskárny

Výbava domácí elektrodílničky

Budoucnost 5G sítí

Velké testy microSD karet a vodních chladičů

Přehled mobilních tarifů

reklama
reklama