Sdílet prostřednictvím


Principy webových služeb technologie ASP.NET AJAX

Scott Cate

Webové služby jsou nedílnou součástí rozhraní .NET, které poskytují multiplatformní řešení pro výměnu dat mezi distribuovanými systémy. Webové služby se obvykle používají k tomu, aby různé operační systémy, objektové modely a programovací jazyky odesílaly a přijímaly data, lze je také použít k dynamickému vkládání dat na stránku ASP.NET AJAX nebo odesílání dat ze stránky do back-endového systému. To vše lze provést, aniž byste se museli uchylovat k operacím postback.

Volání webových služeb pomocí ASP.NET AJAX

Dan Wahlin

Webové služby jsou nedílnou součástí rozhraní .NET, které poskytují multiplatformní řešení pro výměnu dat mezi distribuovanými systémy. Webové služby se obvykle používají k tomu, aby různé operační systémy, objektové modely a programovací jazyky odesílaly a přijímaly data, lze je také použít k dynamickému vkládání dat na stránku ASP.NET AJAX nebo odesílání dat ze stránky do back-endového systému. To vše lze provést, aniž byste se museli uchylovat k operacím postback.

I když ovládací prvek ASP.NET AJAX UpdatePanel poskytuje jednoduchý způsob, jak povolit libovolnou ASP.NET stránku, mohou existovat časy, kdy potřebujete dynamicky přistupovat k datům na serveru bez použití Prvku UpdatePanel. V tomto článku se dozvíte, jak toho dosáhnout vytvořením a využíváním webových služeb na ASP.NET stránkách AJAX.

Tento článek se zaměří na funkce dostupné v základních rozšířeních ASP.NET AJAX a také na ovládacím prvku s podporou webové služby v sadě ASP.NET AJAX Toolkit označované jako AutoCompleteExtender. Zahrnutá témata zahrnují definování webových služeb s podporou AJAX, vytváření klientských proxy serverů a volání webových služeb pomocí JavaScriptu. Dozvíte se také, jak lze volání webové služby provádět přímo do ASP.NET metod stránky.

Konfigurace webových služeb

Při vytvoření nového projektu webu v sadě Visual Studio 2008 obsahuje soubor web.config řadu nových doplňků, které mohou být pro uživatele předchozích verzí sady Visual Studio neznámé. Některé z těchto úprav mapují předponu "asp" na ASP.NET ovládací prvky AJAX, aby je bylo možné použít na stránkách, zatímco jiné definují požadované obslužné rutiny Http a HttpModules. Výpis 1 ukazuje změny <httpHandlers> provedené v elementu web.config, který má vliv na volání webové služby. Výchozí HttpHandler sloužící ke zpracování volání .asmx je odebrán a nahrazena třídy ScriptHandlerFactory umístěnou v sestavení System.Web.Extensions.dll. System.Web.Extensions.dll obsahuje všechny základní funkce používané ASP.NET AJAX.

Výpis 1. konfigurace obslužné rutiny webové služby ASP.NET AJAX

<httpHandlers>
     <remove verb="*" path="*.asmx"/>
     <add verb="*" path="*.asmx" validate="false"
          type="System.Web.Script.Services.ScriptHandlerFactory,
          System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
          PublicKeyToken=31bf3856ad364e35"/>
</httpHandlers>

Tato náhrada httpHandler je provedena tak, aby bylo možné provádět volání JSON (JavaScript Object Notation) ze stránek ASP.NET AJAX do webových služeb .NET pomocí proxy webové služby JavaScriptu. ASP.NET AJAX odesílá zprávy JSON do webových služeb na rozdíl od standardních volání PROTOKOLU SOAP (Simple Object Access Protocol) obvykle přidružená k webovým službám. Výsledkem je celkový počet menších zpráv požadavků a odpovědí. Umožňuje také efektivnější zpracování dat na straně klienta, protože ASP.NET javascriptová knihovna AJAX je optimalizovaná pro práci s objekty JSON. Výpis 2 a Výpis 3 ukazují příklady požadavků webové služby a odpovědí zprávy serializované do formátu JSON. Zpráva požadavku zobrazená v výpisu 2 předá parametr země s hodnotou "Belgie", zatímco zpráva odpovědi v výpisu 3 předává pole objektů Customer a jejich přidružené vlastnosti.

Výpis 2. Zpráva žádosti o webovou službu serializovaná do FORMÁTU JSON

{"country":"Belgium"}

> [! POZNÁMKA] Název operace je definován jako součást adresy URL webové služby; kromě toho se zprávy požadavku neodesílají vždy přes JSON. Webové služby mohou využívat atribut ScriptMethod s parametrem UseHttpGet nastaveným na hodnotu true, což způsobí předání parametrů prostřednictvím parametrů řetězce dotazu.

Výpis 3. Zpráva odpovědi webové služby serializovaná do FORMÁTU JSON

[{"__type":"Model.Customer","Country":"Belgium","CompanyName":"Maison
     Dewey","CustomerID":"MAISD","ContactName":"Catherine
     Dewey"},{"__type":"Model.Customer","Country":"Belgium","CompanyName":"Suprêmes
     délices","CustomerID":"SUPRD","ContactName":"Pascale
     Cartrain"}]

V další části se dozvíte, jak vytvořit webové služby schopné zpracovávat zprávy požadavků JSON a reagovat pomocí jednoduchých i složitých typů.

Vytváření webových služeb s podporou AJAX

Architektura ASP.NET AJAX nabízí několik různých způsobů volání webových služeb. Můžete použít ovládací prvek AutoCompleteExtender (dostupný v sadě ASP.NET AJAX Toolkit) nebo JavaScript. Než ale zavoláte službu, musíte ji povolit ajax, aby ji mohl volat kód klientského skriptu.

Bez ohledu na to, jestli s ASP.NET webovými službami začínáte, můžete jednoduše vytvářet a povolovat služby AJAX. Rozhraní .NET Framework podporuje vytváření webových služeb ASP.NET od jeho počáteční verze v roce 2002 a rozšíření ASP.NET AJAX poskytují další funkce AJAX, které vycházejí z výchozí sady funkcí rozhraní .NET Framework. Visual Studio .NET 2008 Beta 2 má integrovanou podporu pro vytváření souborů webové služby .asmx a automaticky odvozuje přidružený kód vedle tříd z třídy System.Web.Services.WebService. Při přidávání metod do třídy musíte použít Atribut WebMethod, aby je uživatelé webové služby volali.

Výpis 4 ukazuje příklad použití atributu WebMethod na metodu s názvem GetCustomersByCountry().

Výpis 4. Použití atributu WebMethod ve webové službě

[WebMethod]
public Customer[] GetCustomersByCountry(string country)
{
     return Biz.BAL.GetCustomersByCountry(country);
}

Metoda GetCustomersByCountry() přijímá parametr země a vrátí pole objektu Customer. Hodnota země předaná metodě se předá třídě obchodní vrstvy, která pak volá třídu datové vrstvy pro načtení dat z databáze, vyplnění vlastností objektu Customer dat daty a vrácení pole.

Použití atributu ScriptService

Při přidávání atributu WebMethod umožňuje volání metody GetCustomersByCountry() klienty, kteří odesílají standardní zprávy SOAP do webové služby, neumožňuje volání JSON z ASP.NET aplikace AJAX z boxu. Pokud chcete povolit volání JSON, musíte u třídy webové služby použít atribut rozšíření ScriptService ASP.NET AJAX. To webové službě umožňuje odesílat zprávy odpovědí formátované pomocí JSON a umožňuje skript na straně klienta volat službu odesíláním zpráv JSON.

Výpis 5 ukazuje příklad použití atributu ScriptService na třídu webové služby s názvem CustomersService.

Výpis 5. Použití atributu ScriptService k ajax-povolení webové služby

[System.Web.Script.Services.ScriptService]
[WebService(Namespace = "http://xmlforasp.net")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class CustomersService : System.Web.Services.WebService
{
     [WebMethod]
     public Customer[] GetCustomersByCountry(string country)
     {
          return Biz.BAL.GetCustomersByCountry(country);
     }
}

Atribut ScriptService funguje jako značka, která označuje, že je možné ji volat z kódu skriptu AJAX. Ve skutečnosti nezpracuje žádnou z úloh serializace nebo deserializace JSON, které se vyskytují na pozadí. ScriptHandlerFactory (nakonfigurované v souboru web.config) a další související třídy dělají hromadné zpracování JSON.

Použití atributu ScriptMethod

Atribut ScriptService je jediný ASP.NET atribut AJAX, který musí být definován ve webové službě .NET, aby ho mohly používat ASP.NET stránky AJAX. Jiný atribut s názvem ScriptMethod lze však použít také přímo na webové metody ve službě. ScriptMethod definuje tři vlastnosti včetně UseHttpGeta ResponseFormat XmlSerializeString. Změna hodnot těchto vlastností může být užitečná v případech, kdy je potřeba změnit typ požadavku přijatého webovou metodou na GET, pokud webová metoda potřebuje vrátit nezpracovaná data XML ve formě objektu XmlDocument nebo XmlElement objektu nebo při vrácení dat ze služby by měla být vždy serializována jako XML místo JSON.

Vlastnost UseHttpGet lze použít, když webová metoda by měla přijímat požadavky GET na rozdíl od požadavků POST. Požadavky se odesílají pomocí adresy URL se vstupními parametry webové metody převedenými na parametry QueryString. Vlastnost UseHttpGet má výchozí hodnotu false a měla by být nastavena pouze tehdy true , když jsou operace známé jako bezpečné a když se citlivá data nepředají webové službě. Výpis 6 ukazuje příklad použití scriptMethod atributu s UseHttpGet vlastnost.

Výpis 6. Použití ScriptMethod atributu s UseHttpGet vlastnost.

[WebMethod]
[ScriptMethod(UseHttpGet = true)]
public string HttpGetEcho(string input)
{
     return input;
}

Následuje příklad hlaviček odeslaných při vyvolání webové metody HttpGetEcho zobrazené v výpisu 6:

GET /CustomerViewer/DemoService.asmx/HttpGetEcho?input=%22Input Value%22 HTTP/1.1

Kromě toho, že webové metody umožňují přijímat požadavky HTTP GET, lze atribut ScriptMethod použít také v případě, že odpovědi XML musí být vráceny ze služby místo JSON. Například webová služba může načíst informační kanál RSS ze vzdáleného webu a vrátit ho jako XmlDocument nebo XmlElement objekt. Zpracování dat XML pak může nastat v klientovi.

Výpis 7 ukazuje příklad použití ResponseFormat vlastnost určit, že data XML by měla být vrácena z webové metody.

Výpis 7. Použití ScriptMethod atributu s ResponseFormat vlastnost.

[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Xml)]
public XmlElement GetRssFeed(string url)
{
     XmlDocument doc = new XmlDocument();
     doc.Load(url);
     return doc.DocumentElement;
}

Vlastnost ResponseFormat lze také použít spolu s XmlSerializeString vlastnost. XmlSerializeString vlastnost má výchozí hodnotu false, což znamená, že všechny návratové typy s výjimkou řetězců vrácených z webové metody jsou serializovány jako XML, pokud ResponseFormat je vlastnost nastavena na ResponseFormat.Xml. Pokud XmlSerializeString je nastavena na true, všechny typy vrácené z webové metody jsou serializovány jako XML včetně typů řetězců. Pokud ResponseFormat vlastnost má hodnotu ResponseFormat.Json XmlSerializeString vlastnost je ignorována.

Výpis 8 ukazuje příklad použití XmlSerializeString vlastnost vynucení řetězce serializovat jako XML.

Výpis 8. Použití ScriptMethod atributu XmlSerializeString vlastnost

[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Xml,XmlSerializeString=true)]
public string GetXmlString(string input)
{
     return input;
}

Hodnota vrácená voláním GetXmlString Webové metody zobrazené v výpisu 8 je zobrazena dále:

<?xml version="1.0"?>
     <string>Test</string>

I když výchozí formát JSON minimalizuje celkovou velikost zpráv požadavků a odpovědí a je snadněji využit ASP.NET klienty AJAX v křížovém prohlížeči, vlastnosti ResponseFormat a XmlSerializeString lze využít, když klientské aplikace, jako je Internet Explorer 5 nebo vyšší, očekává, že data XML budou vrácena z webové metody.

Práce se složitými typy

Výpis 5 ukázal příklad vrácení komplexního typu s názvem Zákazník z webové služby. Třída Customer definuje několik různých jednoduchých typů interně, jako jsou vlastnosti, jako je FirstName a LastName. Komplexní typy používané jako vstupní parametr nebo návratový typ webové metody s podporou AJAX se před odesláním na straně klienta automaticky serializují do formátu JSON. Vnořené komplexní typy (ty, které jsou definovány interně v jiném typu), ale nejsou ve výchozím nastavení klientovi k dispozici jako samostatné objekty.

V případech, kdy musí být na stránce klienta použit také vnořený komplexní typ používaný webovou službou, lze do webové služby přidat atribut ASP.NET AJAX GenerateScriptType. Například Třída CustomerDetails zobrazená v výpisu 9 obsahuje vlastnosti Address a Gender, které představují vnořené komplexní typy.

Výpis 9. Zde zobrazená třída CustomerDetails obsahuje dva vnořené komplexní typy.

public class CustomerDetails : Customer
{
     public CustomerDetails()
     {
     }
     Address _Address;
     Gender _Gender = Gender.Unknown;
     public Address Address
     {
          get { return _Address; }
          set { _Address = value; }
     }
     public Gender Gender
     {
          get { return _Gender; }
          set { _Gender = value; }
     }
}

Objekty Address a Gender definované v rámci třídy CustomerDetails zobrazené v výpisu 9 nebudou automaticky zpřístupněny pro použití na straně klienta prostřednictvím JavaScriptu, protože jsou vnořené typy (Adresa je třída a Pohlaví je výčet). V situacích, kdy musí být na straně klienta k dispozici vnořený typ použitý v rámci webové služby, lze použít atribut GenerateScriptType uvedený dříve (viz výpis 10). Tento atribut lze přidat vícekrát v případech, kdy se ze služby vrací různé vnořené komplexní typy. Lze ji použít přímo na třídu webové služby nebo nad konkrétní webové metody.

Výpis 10. Použití atributu GenerateScriptService k definování vnořených typů, které by měly být k dispozici pro klienta.

[System.Web.Script.Services.ScriptService]
[System.Web.Script.Services.GenerateScriptType(typeof(Address))]
[System.Web.Script.Services.GenerateScriptType(typeof(Gender))]
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class NestedComplexTypeService : System.Web.Services.WebService
{
     //Web Methods
}

Použitím atributu GenerateScriptType na webovou službu se typy Adresa a pohlaví automaticky zpřístupní pro použití klientem ASP.NET javascriptový kód AJAX. Příklad JavaScriptu, který se automaticky vygeneruje a odesílá klientovi přidáním atributu GenerateScriptType do webové služby, se zobrazí v výpisu 11. V další části článku se dozvíte, jak používat vnořené komplexní typy.

Výpis 11. Vnořené komplexní typy zpřístupněné na stránce ASP.NET AJAX.

if (typeof(Model.Address) === 'undefined')
{
     Model.Address=gtc("Model.Address");
     Model.Address.registerClass('Model.Address');
}
Model.Gender = function() { throw Error.invalidOperation(); }
Model.Gender.prototype = {Unknown: 0,Male: 1,Female: 2}
Model.Gender.registerEnum('Model.Gender', true);

Teď, když jste viděli, jak vytvořit webové služby a zpřístupnit je ASP.NET stránkách AJAX, podívejme se, jak vytvářet a používat proxy javascriptové servery, aby bylo možné načíst nebo odeslat data do webových služeb.

Vytváření proxy serverů JavaScriptu

Volání standardní webové služby (.NET nebo jiné platformy) obvykle zahrnuje vytvoření objektu proxy, který vás chrání před složitostí odesílání požadavků SOAP a odpovědí. S ASP.NET volání webové služby AJAX je možné vytvářet a používat javascriptové proxy servery, které lze snadno volat služby, aniž byste se museli starat o serializaci a deserializaci zpráv JSON. Proxy jazyka JavaScript lze automaticky generovat pomocí ovládacího prvku ASP.NET AJAX ScriptManager.

Vytvoření javascriptového proxy serveru, který může volat webové služby, se provádí pomocí vlastnosti ScriptManager Services. Tato vlastnost umožňuje definovat jednu nebo více služeb, které může stránka AJAX ASP.NET volat asynchronně za účelem odesílání nebo příjmu dat, aniž by bylo nutné provádět operace zpětného odeslání. Službu definujete pomocí ovládacího prvku ASP.NET AJAX ServiceReference a přiřazením adresy URL webové služby k vlastnosti ovládacího prvku Path . Výpis 12 ukazuje příklad odkazování na službu s názvem CustomersService.asmx.

<asp:ScriptManager ID="ScriptManager1" runat="server">
     <Services>
          <asp:ServiceReference Path="~/CustomersService.asmx" />
     </Services>
</asp:ScriptManager>

Výpis 12. Definování webové služby použité na stránce ASP.NET AJAX

Přidání odkazu na CustomersService.asmx prostřednictvím ovládacího prvku ScriptManager způsobí, že se javascriptový proxy server dynamicky vygeneruje a odkazuje na stránku. Proxy server je vložen pomocí <značky skriptu> a dynamicky načten voláním souboru CustomersService.asmx a připojením /js na konec. Následující příklad ukazuje, jak je proxy JavaScript vložen na stránku při ladění je zakázáno ve web.config:

<script src="CustomersService.asmx/js" type="text/javascript"></script>

> [! POZNÁMKA] Pokud chcete zobrazit skutečný kód proxy javascriptu, který je vygenerován, můžete zadat adresu URL požadované webové služby .NET do pole adresa aplikace Internet Explorer a připojit /js na konec.

Pokud je v souboru web.config povolené ladění verze javascriptového proxy serveru, vloží se na stránku, jak je znázorněno dále:

<script src="CustomersService.asmx/jsdebug" type="text/javascript"></script>

JavaScript proxy vytvořený ScriptManager lze také vložit přímo na stránku, nikoli odkazovat pomocí <atributu src značky skriptu> . To lze provést nastavením vlastnosti InlineScript ovládacího prvku ServiceReference na hodnotu true (výchozí hodnota je false). To může být užitečné, když se proxy server nesdílí na více stránkách a kdy chcete snížit počet síťových volání provedených na server. Pokud je inlineScript nastaven na hodnotu true, proxy skript nebude uložen v mezipaměti prohlížeče, takže výchozí hodnota false se doporučuje v případech, kdy proxy server používá více stránek v aplikaci ASP.NET AJAX. Příklad použití vlastnosti InlineScript je zobrazen dále:

<asp:ServiceReference InlineScript="true" Path="~/CustomersService.asmx"/>

Použití proxy javascriptových serverů

Jakmile webová služba odkazuje na stránku ASP.NET AJAX pomocí ovládacího prvku ScriptManager, lze volání webové služby provést a vrácená data lze zpracovat pomocí funkcí zpětného volání. Webová služba je volána odkazem na jeho obor názvů (pokud existuje), název třídy a název webové metody. Všechny parametry předané webové službě lze definovat spolu s funkcí zpětného volání, která zpracovává vrácená data.

Příklad použití javascriptového proxy k volání webové metody s názvem GetCustomersByCountry() se zobrazí v výpisu 13. Funkce GetCustomersByCountry() se volá, když koncový uživatel klikne na tlačítko na stránce.

Výpis 13. Volání webové služby pomocí javascriptového proxy serveru

function GetCustomerByCountry()
{
     var country = $get("txtCountry").value;
     InterfaceTraining.CustomersService.GetCustomersByCountry(country, OnWSRequestComplete);
}
function OnWSRequestComplete(results)
{
     if (results != null)
     {
          CreateCustomersTable(results);
          GetMap(results);
     }
}

Toto volání odkazuje na interfaceTraining obor názvů, CustomersService třídy a GetCustomersByCountry Web Method definované ve službě. Předává hodnotu země získanou z textového pole a funkci zpětného volání s názvem OnWSRequestComplete, která by se měla vyvolat, když asynchronní volání webové služby vrátí. OnWSRequestComplete zpracovává pole objektů Customer vrácených ze služby a převede je na tabulku zobrazenou na stránce. Výstup vygenerovaný z volání se zobrazí na obrázku 1.

Vytvoření vazby dat získaných provedením asynchronního volání AJAX do webové služby

Obrázek 1: Vytvoření vazby dat získaných provedením asynchronního volání AJAX do webové služby (Kliknutím zobrazíte obrázek s plnou velikostí.

Proxy jazyka JavaScript můžou také volat jednosměrná volání webových služeb v případech, kdy by se měla volat webová metoda, ale proxy server by neměl čekat na odpověď. Můžete například volat webovou službu, která spustí proces, jako je pracovní tok, ale nečeká na návratovou hodnotu ze služby. V případech, kdy je potřeba provést jednosměrné volání do služby, může být funkce zpětného volání zobrazená v výpisu 13 jednoduše vynechána. Vzhledem k tomu, že není definována žádná funkce zpětného volání, objekt proxy nebude čekat, až webová služba vrátí data.

Zpracování chyb

Asynchronní zpětná volání webových služeb můžou narazit na různé typy chyb, jako je mimo provoz sítě, nedostupná webová služba nebo vrácená výjimka. Naštěstí objekty proxy jazyka JavaScript generované ScriptManager umožňují definovat více zpětných volání, aby bylo možné zpracovat chyby a chyby kromě zpětného volání úspěchu zobrazeného dříve. Funkci zpětného volání chyby lze definovat ihned po standardní funkci zpětného volání ve volání webové metody, jak je znázorněno v výpisu 14.

Výpis 14. Definování funkce zpětného volání chyby a zobrazení chyb

function GetCustomersByCountry() 
{
     var country = $get("txtCountry").value;
     InterfaceTraining.CustomersService.GetCustomersByCountry(country, 
          OnWSRequestComplete, OnWSRequestFailed);
}
function OnWSRequestFailed(error)
{
     alert("Stack Trace: " + error.get_stackTrace() + "/r/n" +
          "Error: " + error.get_message() + "/r/n" +
          "Status Code: " + error.get_statusCode() + "/r/n" +
          "Exception Type: " + error.get_exceptionType() + "/r/n" +
          "Timed Out: " + error.get_timedOut());
}

Všechny chyby, ke kterým dojde při volání webové služby, aktivují funkci zpětného volání OnWSRequestFailed(), která přijímá objekt představující chybu jako parametr. Objekt chyby zveřejňuje několik různých funkcí pro určení příčiny chyby a také to, zda vypršel časový limit volání. Výpis 14 ukazuje příklad použití různých chybových funkcí a obrázek 2 ukazuje příklad výstupu vygenerovaného funkcemi.

Výstup vygenerovaný voláním ASP.NET chybových funkcí AJAX

Obrázek 2: Výstup vygenerovaný voláním ASP.NET chybových funkcí AJAX (Kliknutím zobrazíte obrázek s plnou velikostí.

Zpracování dat XML vrácených z webové služby

Dříve jste viděli, jak webová metoda může vrátit nezpracovaná data XML pomocí ScriptMethod atributu spolu s jeho ResponseFormat vlastnost. Pokud je Vlastnost ResponseFormat nastavena na ResponseFormat.Xml, data vrácená z webové služby jsou serializována jako XML místo JSON. To může být užitečné, když data XML musí být předána přímo klientovi ke zpracování pomocí JavaScriptu nebo XSLT. V současné době internet Explorer 5 nebo vyšší poskytuje nejlepší objektový model na straně klienta pro analýzu a filtrování dat XML z důvodu integrované podpory MSXML.

Načítání dat XML z webové služby se neliší od načítání jiných datových typů. Začněte vyvoláním javascriptového proxy serveru pro volání příslušné funkce a definováním funkce zpětného volání. Jakmile se volání vrátí, můžete zpracovat data ve funkci zpětného volání.

Výpis 15 ukazuje příklad volání webové metody s názvem GetRssFeed(), která vrací XmlElement objektu. GetRssFeed() přijímá jeden parametr představující adresu URL pro načtení informačního kanálu RSS.

Výpis 15. Práce s daty XML vrácenými z webové služby

function GetRss()
{
     InterfaceTraining.DemoService.GetRssFeed(
          "https://blogs.interfacett.com/dan-wahlins-blog/rss.xml",
          OnWSRequestComplete);
}
function OnWSRequestComplete(result)
{
     if (document.all) //Filter for IE DOM since other browsers are limited
     {
          var items = result.selectNodes("//item");
          for (var i=0;i<items.length;i++)
          {
               var title = items[i].selectSingleNode("title").text;
               var href = items[i].selectSingleNode("link").text;
               $get("divOutput").innerHTML +=
               "<a href='" + href + "'>" + title + "</a><br/>";
          }
     }
     else
     {
          $get("divOutput").innerHTML = "RSS only available in IE5+";
     }
}

Tento příklad předá adresu URL informačnímu kanálu RSS a zpracuje vrácená data XML ve funkci OnWSRequestComplete(). OnWSRequestComplete() nejprve zkontroluje, jestli je prohlížeč Internet Explorer a zjistí, jestli je analyzátor MSXML dostupný nebo ne. Pokud ano, použije se příkaz XPath k vyhledání všech <značek položek> v informačním kanálu RSS. Každá položka se pak itehodnotuje a přidružené <názvy> a <značky odkazů> se nacházejí a zpracovávají, aby se zobrazila data jednotlivých položek. Obrázek 3 ukazuje příklad výstupu vygenerovaného z volání ASP.NET AJAX prostřednictvím javascriptového proxy do metody GetRssFeed().

Zpracování složitých typů

Komplexní typy přijaté nebo vrácené webovou službou se automaticky zveřejňují prostřednictvím javascriptového proxy serveru. Vnořené komplexní typy však nejsou přímo přístupné na straně klienta, pokud není u služby použit atribut GenerateScriptType, jak je popsáno výše. Proč chcete použít vnořený komplexní typ na straně klienta?

Pokud chcete odpovědět na tuto otázku, předpokládejme, že stránka ASP.NET AJAX zobrazuje zákaznická data a umožňuje koncovým uživatelům aktualizovat adresu zákazníka. Pokud webová služba určuje, že typ adresy (komplexní typ definovaný v rámci třídy CustomerDetails) lze odeslat klientovi, pak proces aktualizace lze rozdělit do samostatných funkcí pro lepší opětovné použití kódu.

Výstup vytvoření z volání webové služby, která vrací data RSS.

Obrázek 3: Výstup při volání webové služby, která vrací data RSS (Kliknutím zobrazíte obrázek s plnou velikostí.

Výpis 16 ukazuje příklad kódu na straně klienta, který vyvolá objekt Address definovaný v oboru názvů modelu, vyplní ho aktualizovanými daty a přiřadí ho k vlastnosti Adresa objektu CustomerDetails. Objekt CustomerDetails se pak předá webové službě ke zpracování.

Výpis 16. Použití vnořených komplexních typů

function UpdateAddress()
{
     var cust = new Model.CustomerDetails();
     cust.CustomerID = $get("hidCustomerID").value;
     cust.Address = CreateAddress();
     InterfaceTraining.DemoService.UpdateAddress(cust,OnWSUpdateComplete);
}
function CreateAddress()
{
     var addr = new Model.Address();
     addr.Street = $get("txtStreet").value;
     addr.City = $get("txtCity").value;
     addr.State = $get("txtState").value;
     return addr;
}
function OnWSUpdateComplete(result)
{
     alert("Update " + ((result)?"succeeded":"failed")+ "!");
}

Vytváření a používání metod stránky

Webové služby poskytují vynikající způsob, jak vystavit opakovaně použitelné služby různým klientům, včetně ASP.NET stránek AJAX. Můžou ale existovat případy, kdy stránka potřebuje načíst data, která nikdy nebudou použita ani nebudou sdílena jinými stránkami. V tomto případě se může zdát, že vytvoření souboru .asmx, který umožní stránce přístup k datům, se může zdát jako nadměrné, protože služba je používána pouze jednou stránkou.

ASP.NET AJAX poskytuje další mechanismus pro vytváření volání podobných webové službě bez vytváření samostatných souborů .asmx. To se provádí pomocí techniky označované jako "metody stránky". Metody stránky jsou statické (sdílené v VB.NET) metody vložené přímo do souboru stránky nebo kódu, které mají atribut WebMethod použitý na ně. Použitím atributu WebMethod lze volat pomocí speciálního javascriptového objektu s názvem PageMethods, který se dynamicky vytvoří za běhu. PageMethods objekt funguje jako proxy, který vás chrání před procesem serializace/deserializace JSON. Všimněte si, že chcete-li použít PageMethods objektu, musíte nastavit ScriptManager EnablePageMethods vlastnost true.

<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true">
</asp:ScriptManager>

Výpis 17 ukazuje příklad definování dvou stránkových metod v ASP.NET kódu vedle třídy. Tyto metody načítají data z třídy obchodní vrstvy umístěné ve složce App_Code webu.

Výpis 17. Definování metod stránky

[WebMethod]
public static Customer[] GetCustomersByCountry(string country)
{
     return Biz.BAL.GetCustomersByCountry(country);
}
[WebMethod]
public static Customer[] GetCustomersByID(string id)
{
     return Biz.BAL.GetCustomersByID(id);
}

Když ScriptManager zjistí přítomnost webových metod na stránce, vygeneruje dynamický odkaz na PageMethods objekt uvedený dříve. Volání webové metody je dosaženo odkazem Na PageMethods třídy následované názvem metody a všechny nezbytné parametr data, které by měly být předány. Výpis 18 ukazuje příklady volání dvou stránkových metod zobrazených dříve.

Výpis 18. Volání metod stránky pomocí PageMethods JavaScript objektu.

function GetCustomerByCountry() 
{
     var country = $get("txtCountry").value;
     PageMethods.GetCustomersByCountry(country, OnWSRequestComplete);
}
function GetCustomerByID() 
{
     var custID = $get("txtCustomerID").value;
     PageMethods.GetCustomersByID(custID, OnWSRequestComplete);
}
function OnWSRequestComplete(results) 
{
     var searchResults = $get("searchResults");
     searchResults.control.set_data(results);
     if (results != null) GetMap(results[0].Country,results);
}

Použití PageMethods objektu je velmi podobné použití javascriptového proxy objektu. Nejprve zadáte všechna data parametrů, která by se měla předat metodě stránky, a pak definujete funkci zpětného volání, která by se měla volat, když asynchronní volání vrátí. Můžete také zadat zpětné volání selhání (příklad zpracování selhání najdete v výpisu 14).

AutoCompleteExtender a ASP.NET AJAX Toolkit

Sada ASP.NET AJAX Toolkit (dostupná z https://github.com/DevExpress/AjaxControlToolkit) nabízí několik ovládacích prvků, které lze použít pro přístup k webovým službám. Konkrétně sada nástrojů obsahuje užitečný ovládací prvek s názvem AutoCompleteExtender , který lze použít k volání webových služeb a zobrazení dat na stránkách bez psaní javascriptového kódu vůbec.

Ovládací prvek AutoCompleteExtender lze použít k rozšíření stávajících funkcí textového pole a snadnějšímu vyhledání dat, která uživatelé hledají. Při psaní do textového pole lze ovládací prvek použít k dotazování webové služby a zobrazuje výsledky pod textovým polem dynamicky. Obrázek 4 ukazuje příklad použití ovládacího prvku AutoCompleteExtender k zobrazení ID zákazníků pro aplikaci podpory. Když uživatel zadá do textového pole různé znaky, zobrazí se pod ním různé položky na základě jejich vstupu. Uživatelé pak můžou vybrat požadované ID zákazníka.

Použití funkce AutoCompleteExtender na stránce ASP.NET AJAX vyžaduje, aby se sestavení AjaxControlToolkit.dll přidalo do složky přihrádky webu. Po přidání sestavení sady nástrojů na něj budete chtít odkazovat v souboru web.config, aby ovládací prvky, které obsahuje, byly k dispozici pro všechny stránky v aplikaci. Můžete to provést přidáním následující značky do značky <ovládacích prvků> web.config:

<add namespace="AjaxControlToolkit" assembly="AjaxControlToolkit" tagPrefix="ajaxToolkit"/>

V případech, kdy potřebujete ovládací prvek použít jenom na konkrétní stránce, můžete na něj odkazovat přidáním direktivy Odkaz na začátek stránky, jak je znázorněno dále, místo aktualizace web.config:

<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" 
     TagPrefix="ajaxToolkit" %>

Použití ovládacího prvku AutoCompleteExtender.

Obrázek 4: Použití ovládacího prvku AutoCompleteExtender (Kliknutím zobrazíte obrázek s plnou velikostí.

Jakmile je web nakonfigurovaný tak, aby používal sadu nástrojů ASP.NET AJAX, můžete na stránku přidat ovládací prvek AutoCompleteExtender, podobně jako byste přidali běžný ovládací prvek serveru ASP.NET. Výpis 19 ukazuje příklad použití ovládacího prvku k volání webové služby.

Výpis 19. Použití ASP.NET AJAX Toolkit AutoCompleteExtender ovládacího prvku.

<ajaxToolkit:AutoCompleteExtender ID="extTxtCustomerID" runat="server"
     MinimumPrefixLength="1" ServiceMethod="GetCustomerIDs"
     ServicePath="~/CustomersService.asmx"
     TargetControlID="txtCustomerID" />

AutoCompleteExtender má několik různých vlastností, včetně standardního ID a runat vlastností nalezených na serverových ovládacích prvcích. Kromě toho umožňuje definovat, kolik znaků koncový uživatel zadá před dotazem webové služby na data. Vlastnost MinimumPrefixLength zobrazená v výpisu 19 způsobí, že služba bude volána při každém zadání znaku do textového pole. Tuto hodnotu budete chtít pečlivě nastavit, protože pokaždé, když uživatel zadá znak webové služby, bude volána k hledání hodnot, které odpovídají znakům v textovém poli. Webová služba pro volání i cílovou webovou metodu jsou definovány pomocí ServicePath a ServiceMethod vlastnosti v uvedeném pořadí. Nakonec TargetControlID vlastnost identifikuje, které textové pole připojit AutoCompleteExtender ovládací prvek.

Volaná webová služba musí mít použitý atribut ScriptService, jak je popsáno dříve, a cílová webová metoda musí přijmout dva parametry s názvem prefixText a count. Parametr prefixText představuje znaky zadané koncovým uživatelem a parametr count představuje, kolik položek se má vrátit (výchozí hodnota je 10). Výpis 20 ukazuje příklad GetCustomerIDs Web Method volal AutoCompleteExtender ovládací prvek zobrazený dříve v listing 19. Webová metoda volá metodu obchodní vrstvy, která pak volá metodu datové vrstvy, která zpracovává filtrování dat a vrací odpovídající výsledky. Kód metody datové vrstvy se zobrazí v výpisu 21.

Výpis 20. Filtrování dat odeslaných z ovládacího prvku AutoCompleteExtender

[WebMethod]
public string[] GetCustomerIDs(string prefixText, int count) 
{
     return Biz.BAL.GetCustomerIDs(prefixText, count);
}

Výpis 21. Filtrování výsledků na základě vstupu koncového uživatele

public static string[] GetCustomerIDs(string prefixText, int count)
{
     //Customer IDs cached in _CustomerIDs field to improve performance
     if (_CustomerIDs == null)
     {
          List<string> ids = new List<string>();
          //SQL text used for simplicity...recommend using sprocs
          string sql = "SELECT CustomerID FROM Customers";
          DbConnection conn = GetDBConnection();
          conn.Open();
          DbCommand cmd = conn.CreateCommand();
          cmd.CommandText = sql;
          DbDataReader reader = cmd.ExecuteReader();
          while (reader.Read())
          {
               ids.Add(reader["CustomerID"].ToString());
          }
          reader.Close();
          conn.Close();
          _CustomerIDs = ids.ToArray();
     }
     int index = Array.BinarySearch(_CustomerIDs, prefixText, new CaseInsensitiveComparer());
     //~ is bitwise complement (reverse each bit)
     if (index < 0) index = ~index;
     int matchingCount;
     for (matchingCount = 0; matchingCount < count && index + matchingCount < _CustomerIDs.Length; matchingCount++)
     {
          if (!_CustomerIDs[index + matchingCount].StartsWith(prefixText, StringComparison.CurrentCultureIgnoreCase))
          {
               break;
          }
     }
     String[] returnValue = new string[matchingCount];
     if (matchingCount > 0)
     {
          Array.Copy(_CustomerIDs, index, returnValue, 0, matchingCount);
     }
     return returnValue;
}

Závěr

ASP.NET AJAX poskytuje vynikající podporu pro volání webových služeb bez psaní velkého množství vlastního javascriptového kódu pro zpracování zpráv požadavků a odpovědí. V tomto článku jste se naučili, jak povolit webové služby .NET AJAX, aby mohly zpracovávat zprávy JSON a jak definovat proxy jazyka JavaScript pomocí ovládacího prvku ScriptManager. Také jste viděli, jak lze proxy jazyka JavaScript použít k volání webových služeb, zpracování jednoduchých a složitých typů a řešení selhání. Nakonec jste viděli, jak se dají metody stránky použít ke zjednodušení procesu vytváření a volání webové služby a jak může ovládací prvek AutoCompleteExtender poskytnout koncovým uživatelům pomoc při psaní. Ačkoli updatePanel dostupný v ASP.NET AJAX bude jistě ovládací prvek pro mnoho programátorů AJAX kvůli své jednoduchosti, znalost volání webových služeb prostřednictvím javascriptových proxy může být užitečná v mnoha aplikacích.

Životopis

Dan Wahlin (Microsoft Most Valuable Professional for ASP.NET a XML Web Services) je instruktor a konzultant architektury pro vývoj .NET na technickém školení (http://www.interfacett.comInterface Technical Training). Dan založil XML pro web ASP.NET vývojářů (www.XMLforASP.NET), je na úřadu mluvčího INETA a hovoří na několika konferencích. Dan spoluvytvořený Professional Windows DNA (Wrox), ASP.NET: Tipy, kurzy a kód (Sams), ASP.NET 1.1 Insider Solutions, Professional ASP.NET 2.0 AJAX (Wrox), ASP.NET 2.0 MVP Hacks a authored XML for ASP.NET Developers (Sams). Když nepíše kód, články nebo knihy, Dan si užívá hudbu a nahrává hudbu a hraje golf a basketbal se svou ženou a dětmi.

Scott Cate pracuje s webovými technologiemi Microsoftu od roku 1997 a je prezidentem myKB.com (www.myKB.com), kde se specializuje na psaní ASP.NET aplikací zaměřených na softwarová řešení znalostní báze Knowledge Base. Scott může být kontaktován e-mailem na scott.cate@myKB.com ScottCate.com