XML adatkötés a gyakorlatban

Korábban már írtam arról, hogy az MSDN Kompetencia Központ RSS feedjét a FeedBurner szolgáltatás segítségével mérjük. A FeedBurner biztosít egy webes felületet a statisztikai adatok lekérdezéséhez, de ezen kívül egy REST-es API-t is ad, ami lehetővé teszi, hogy közvetlenül saját alkalmazásunkban jelenítsük meg ezeket az adatokat.

Az Awareness API legegyszerűbb metódusának meghívásához egy HTTP GET kérést kell küldenünk a szervernek az alábbi formában:

http://api.feedburner.com/awareness/1.0/GetFeedData?uri=myfeeduri

A válasz pedig az alábbi szerkezetű XML:

<?xml version="1.0" encoding="UTF-8"?>
<rsp stat="ok">
    <!-- This information is part of the FeedBurner Awareness API. 
         If you want to hide this information, you may do so via your FeedBurner Account. -->
    <feed id="1352372" uri="myfeeduri">
        <entry date="2008-06-01" circulation="27" hits="161" />
    </feed>
</rsp>

A lényeg természetesen a date, circulation és hits attribútumokban van, a feladat ezeknek a megjelenítése. Egyedül arra kell odafigyelnünk, hogy a válasz csak abban az esetben érvényes, ha a stat attribútum értéke ok. Ellenkező esetben kissé eltérő a válasz felépítése és a hibaüzenetet egy err elem msg attribútumában kapjuk meg.

LINQ to XML

Miután van már LINQ XML-hez is, csábító, hogy ezzel oldjuk meg a feladatot. Ehhez mindössze ennyi kódot kell írnunk:

    XDocument doc = XDocument.Load( url );
    string status = doc.Root.Attribute( "stat" ).Value;

    if( status.Equals( "ok", StringComparison.OrdinalIgnoreCase ) )
    {
        XElement entry = doc.Descendants( "entry" ).First();
        string date = entry.Attribute( "date" ).Value;
        string circulation = entry.Attribute( "circulation" ).Value;
        string hits = entry.Attribute( "hits" ).Value;

        // TODO: Megjelenítés vezérlőkben...
    }
    else
    {
        string error = doc.Descendants( "err" ).First().Attribute( "msg" ).Value;

        // TODO: hibaüzenet megjelenítése
    }

Ez persze jól működik, de mégis elgondolkodtam azon, hogy mindezt meg lehet-e oldani deklaratív módon, C# kód nélkül?

XML adatkötés

A jó hír az, hogy pontosan erre szolgál az XML adatkötés, ami már ASP.NET 2.0 óta elérhető, csak éppen szeretünk megfeledkezni róla. Ha mégis eszünkbe jut, akkor hajlamosak vagyunk hierarchikus adatszerkezetekkel társítani és csak hierarchikus vezérlőkben, menü vagy fa kontrollokban gondolkodni. Pedig az XML adatkötés tökéletesen működik GridView vagy az új ListView vezérlőkkel is.

Először szükségünk lesz egy XmlDataSource vezérlőre:

    <asp:XmlDataSource ID="xdsFeedService" runat="server" 
        XPath="//rsp/feed/entry" 
        DataFile="http://api.feedburner.com/awareness/1.0/GetFeedData?uri=myfeeduri" />

A DataFile paraméterben akár HTTP-s URL-t is megadhatunk, az XPath attribútum pedig arra szolgál, hogy a válasz XML-ból kiemeljünk egy részt egy XPath kifejezés segítségével, jelen esetben az entry tag-et.

A megjelenítéshez egy ListView vezérlőt használhatunk, ezzel ugyanis pontosan kézben tartható a generált HTML kód. Például így:

    <asp:ListView runat="server" DataSourceID="xdsFeedService">
      <LayoutTemplate>
        <asp:PlaceHolder runat="server" ID="itemPlaceholder" />
      </LayoutTemplate>
        
      <ItemTemplate>
        <asp:PlaceHolder runat="server" 
          Visible='<%# XPath("//rsp/@stat").ToString().Equals( "ok", StringComparison.OrdinalIgnoreCase ) %>'>                
          Date: <asp:Literal runat="server" Text='<%# XPath("@date") %>' />
          <br />
          Circulation: <asp:Literal runat="server" Text='<%# XPath("@circulation") %>' />
          <br />
          Hits: <asp:Literal runat="server" Text='<%# XPath("@hits") %>' />                        
        </asp:PlaceHolder>
                
        <asp:PlaceHolder runat="server" 
          Visible='<%# !XPath("//rsp/@stat").ToString().Equals( "ok", StringComparison.OrdinalIgnoreCase ) %>'>
          Error: <asp:Literal runat="server" Text='<%# XPath("//rsp/err/@msg") %>' />
        </asp:PlaceHolder>
      </ItemTemplate>
    </asp:ListView>

Néhány érdekesség a fenti kódból:

  1. A ListView vezérlőnek szüksége van egy itemPlaceholder azonosítójú vezérlőre az oldalon, amit én egy LayoutTemplate megadásával oldottam meg.
  2. Az XML adatkötéshez nem az Eval, hanem az XPath metódust kell használnunk, aminek egy XPath kifejezést kell megadnunk. Mivel az XmlDataSource-ban már leszűkítettük a válasz XML-t, most olyan XPath kifejezéseket kellett írnom, amelyek ebben a leszűkített kontextusban értelmezhetőek. A @hits például az aktuális entry elem hits attribútumára vonatkozik, míg a //rsp/err/@msg megadásával gyökér relatív útvonalat adtam meg.
  3. Az ItemTemplate-et kettébontottam két Placeholder segítségével, és amennyiben a válasz helyes az elsőt jelenítem meg, amennyiben pedig hibaüzenetet kapunk vissza, a második Placeholdert használom. Az elrejtéshez szintén XML adatkötést használtam, a Visible tulajdonságban szereplő kifejezés a stat attribútum értékét vizsgálja.
  4. Minden esetben a legegyszerűbb vezérlőt használtam, nem Labelt és Panelt, hanem Literalt és Placeholdert. Ezek nem generálnak extra kódot a kimenetbe, de támogatják az adatkötést.

Érdemes megfigyelni, hogy ez a megoldás teljesen deklaratív, nem igényel C# kódot.

Felmerülhet a kérdés, hogy akkor most melyik a jobb? Én általában jobban szeretem a deklaratív megoldást, mert számomra általában áttekinthetőbb és így a kód karbantarthatóbb. Webalkalmazásról lévén szó, természetesen a teljesítmény is fontos szempont, marad tehát a mérés, mérés, mérés.



Balássy György (MS RD, ASP.NET MVP, MCTS)

Balássy György (MS RD, ASP.NET MVP, MCTS) Villamosmérnök, a BME Automatizálási és Alkalmazott Informatikai Tanszékén webportálok fejlesztését oktatja. 2000 óta foglalkozik a Microsoft .NET platformjával, melynek meghonosításában jelentős szerepet vállalt előadóként, konzulensként és A .NET Framework és programozása című könyv társszerzőjeként. Az MSDN Kompetencia Központon belül a Portál Technológiák Csoport vezetője, szakterülete web alapú rendszerek fejlesztése és üzemeltetése. 2004-ben Magyarországon elsőként kapta meg a Most Valuable Professional címet, majd 2005 óta a Microsoft magyarországi regionális igazgatója. Publikációi a Technet Magazinban, az MSDN Kompetencia Központ honlapján és szakmai blogjában olvashatóak.

2008.06.04. 8:07:14 | Permalink | Hozzászólások: 0 | Tárgyszavak: , , , ,


  • LinqDataSource mint ObjectDataSource

    Balássy György (MS RD, ASP.NET MVP, MCTS) A LINQ óriási előnye, hogy a relációs adatainkat szinte észrevétlenül fordítja át objektumok halmazára, emiatt a LinqDataSource inkább rokon az ObjectDataSource vezérlővel, mint az SqlDataSource-szal. Íme egy példa ennek illusztrálására. Tovább »
  • ASP.NET AJAX 4: Kliens oldali adatkötés - alapok

    Balássy György (MS RD, ASP.NET MVP, MCTS) Több, mint 2 éve, hogy először írtam lelkendezve a kliens oldali deklaratív adatkötésről. Akkor mindez az ASP.NET Futures részeként, mintegy előzetesként volt elérhető, és ahogy a 2007-es Web Konferencián be is mutattam, az XML-Script volt a fő csapásirány. Aztán tavaly nyáron jött a hír, hogy az XML-Script megy a kukába, és az ASP.NET AJAX-ban egy teljesen új megvalósítással fogunk találkozni. Tovább »


Írja meg Ön is véleményét!


Hozzászólásokat csak regisztrált, bejelentkezett felhasználóktól tudunk elfogadni!

Hozzászólások