ASP.NET AJAX 4: Kliens oldali adatkötés - webszolgáltatáshoz

A cikksorozat előző részében bemutattam, hogyan használhatjuk az ASP.NET AJAX 4 kliens oldali DataView vezérlőjét helyi változókban tárolt adatok adatkötéssel történő megjelenítéséhez. Ebben a részben kiszakadunk a böngészőből és egy webszolgáltatástól kérjük le az adatokat.

A webszolgáltatás elkészítése

A feladat ugyanaz, mint az előző cikkben, országok listáját akarjuk megjeleníteni, ezért készítettem egy Country osztályt, amiben semmi logika nincs, csak összefogja a Name és Capital tulajdonságokat. Mivel ASMX webszolgáltatásból akarom használni, ezért fontos, hogy legyen neki paraméter nélküli konstruktora.

Ezek után készítettem egy CountryWebService.asmx nevű fájlt, benne a CountryService osztállyal. Fontos, hogy mivel AJAX-ból akarjuk meghívni ezt a webszolgáltatást, ezért nem csak a WebSerice, hanem a ScriptService attribútumot is rá kell ragasztanunk.

A webszolgáltatás osztályban készítettem egy privát List<Country> típusú mezőt, ami az adatbázisunkat reprezentálja, ezen fognak futni a kliens lekérdezések.

Eddig tehát semmi extra, itt tartunk:

  [WebService( Namespace = "http://balassy.spaces.live.com/Samples/" )]
  [WebServiceBinding( ConformsTo = WsiProfiles.BasicProfile1_1 )]
  [System.Web.Script.Services.ScriptService]
  public class CountryWebService : System.Web.Services.WebService
  {
    private List<Country> countries;

    public CountryWebService()
    {
        this.countries = new List<Country>()
        {
            new Country( "Austria", "Vienna" ),
            new Country( "Australia", "Canberra" ),
            // És még jó sok további Country...
        };
    }
  }

A WebMethodot úgy írtam meg, hogy paraméterként megkaphassa, hogy az országok neve vagy fővárosa szerint, illetve növekvő vagy csökkenő sorrendben kívánja a kliens megkapni az adatokat:

  [WebMethod]
  public Country[] GetCountries( string orderby, bool asc )
  {
    Func<Country, string> keySelector;        

    switch( orderby )
    {
        case "Name":
            keySelector = new Func<Country, string>( c => c.Name );
            break;
        case "Capital":
            keySelector = new Func<Country, string>( c => c.Capital );
            break;
        default:
            keySelector = new Func<Country, string>( c => c.Name );
            break;
    }

    IEnumerable<Country> result = asc ? 
this.countries.OrderBy( keySelector ) :
this.countries.OrderByDescending( keySelector ); return result.ToArray(); }

Ugyanez WCF-ben

Ha ugyanezt a webszolgáltatást nem ASMX-ben, hanem WCF-ben akarjuk elkészíteni, akkor kicsit többet kell dolgoznunk vele. Ugyanúgy szükségünk lesz egy CountryService osztályra és benne egy GetCountries metódusra, amiket szokás szerint meg kell jelölnünk a ServiceContract és OperationContract attribútumokkal. Továbbá mivel a szolgáltatás Country példányokat ad vissza, arra kellenek a DataContract és DataMember attribútumok.

Mivel a WCF szolgáltatásunkat AJAX-ból akarjuk meghívni, még nem vagyunk készen. Először is kell a szolgáltatás osztályunkra az AspNetCompatibilityRequirements attribútum:

  [AspNetCompatibilityRequirements( 
RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed )]

Továbbá – mint minden WCF szolgáltatáshoz, ehhez is – feltétlenül szükség van egy gigantikus méretű, alig átlátható konfigurációs XML-re a web.config fájlba:

  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
    <behaviors>
        <endpointBehaviors>
            <behavior name="CountryServiceAspNetAjaxBehavior">
                <enableWebScript />
            </behavior>
        </endpointBehaviors>
        <serviceBehaviors>
            <behavior name="CountryServiceBehavior">
                <serviceMetadata httpGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="true" />
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <services>
        <service behaviorConfiguration="CountryServiceBehavior" name="CountryService">
            <endpoint address="" binding="webHttpBinding" 
contract="CountryService"
behaviorConfiguration="CountryServiceAspNetAjaxBehavior" /> </service> </services> </system.serviceModel>

A sok beállítás közül a két legfontosabb a webHttpBinding és az enableWebScript.

Ha eddig készen vagyunk, akkor a kliensnek már mindegy, hogy milyen technológia dolgozik szerver oldalon.

Kliens oldali adatkötés deklaratívan

Az adatkötéshez kliens oldalon megint csak egy egyszerű HTML fájlt készítettem, benne script blokkokkal pedig betöltöttem az ASP.NET AJAX 4 JavaScript fájljait az ajax.microsoft.com CDN-ről. Az országok felsorolását most is ul-li listában végezzük el a kliens oldali DataView vezérlő segítségével, ami deklaratívan mindössze ennyi:

  <ul
      class="sys-template"
      sys:attach="dv"
      dv:autofetch="true"
      dv:dataprovider="Services/CountryWebService.asmx"
      dv:fetchoperation="GetCountries"
      dv:fetchparameters="{{ { orderby: 'Name', asc: true } }}" >
      <li>
          {{ Name }} ({{ Capital }}) 
      </li>
  </ul>

dv:dataprovider

A DataView dataProvider tulajdonságával adjuk meg, hogy honnan jönnek az adatok. Ez lehet egy sima JSONos webszolgáltatás URI, egy Sys.Net.WebServiceProxy példány vagy bármilyen osztály, ami implementálja a Sys.Data.IDataProvider interfészt, azaz van fetchData metódusa. Az utóbbira példa a Sys.Data.AdoNetServiceProxy osztály, amivel ADO.NET Data Services (Astoria) szolgáltatásokat hívhatunk meg, a legegyszerűbb esetben pedig közvetlenül rámutathatunk az .asmx vagy az .svc fájlra.

dv:fetchoperation

A DataView a fetchOperation tulajdonságban várja annak a metódusnak a nevét, amit a webszolgáltatáson meg akarunk hívni. Ide lehet query stringet is írni, ami ADO.NET Data Services (Astoria) esetén további lehetőségeket ad szűrésre, rendezésre, lapozásra.

dv:fetchparameters

A fetchParameters tulajdonságon keresztül paraméterezhetjük fel a meghívandó webmetódusunkat. Egyetlen JSON “dictionary”-t kell csak összeállítanunk.

dv:autofetch

Az autoFetch tulajdonság true-ra állításával adhatjuk meg, hogy a DataView az oldal betöltődésekor azonnal forduljon az adatforráshoz és töltse fel magát adatokkal. Ha ezt false-ra állítjuk, akkor nekünk kell meghívni a fetchData metódust, például így (feltételezve, hogy a fenti ul elemet elláttuk egy id=”list” attribútummal):

  $find('list').fetchData();

Kliens oldali adatkötés kódból

Természetesen itt is van lehetőség arra, hogy a HTML markupot és az adatkötést szétválasszuk, tehát a teljes adatkötést tisztán kódból végezzük el. Csupaszítsuk le a markupot (az előző cikkben bemutattam, hogyan lehet a {{}} elemektől megszabadulni, itt most csak az adatforrás kezelésére koncentrálok, ezért ezeket most meghagytam):

  <ul
    id="list"
    class="sys-template" >
    <li>
        {{ Name }} ({{ Capital }}) 
    </li>
  </ul>

Az adatkötést pedig az oldal inicializálásakor végezzük el, így:

  <script type="text/javascript">
    Sys.Application.add_init(appInit);
    function appInit()
    {
        $create(
            Sys.UI.DataView,
            {
              autoFetch: false,    // Hogy legyen lehetőségünk még inicializálni
              dataProvider: "Services/CountryService.svc",
              fetchOperation: "GetCountries",
              fetchParameters: { orderby: 'Name', asc: true }
            },
            null,
            null,
            $get("list")
        );
        // Ide jöhetne további inicializálás...
        $find('list').fetchData();
    }
  </script>

Ennyi, ki lehet próbálni, működni fog.

Rendezés

Miután rátettük a kezünket a fetchParameters tulajdonságra, semmi akadálya, hogy a felhasználó határozza meg, milyen sorrendben akarja látni az adatokat. Hogy egyszerűbb legyen az életünk, a rendezés adatait és a DataView vezérlőt kiemelhetjük globális fetchParams és dv változókba:

  var fetchParams = { orderby: 'Name', asc: true }
  var dv;
  Sys.Application.add_init(appInit);
  function appInit()
  {
      $create
( Sys.UI.DataView, { autoFetch: false,
dataProvider: "Services/CountryService.svc", fetchOperation: "GetCountries", fetchParameters: fetchParams }, null, null, $get("list") );
      dv = $find('list');
      dv.fetchData();
  }

Kellene még két metódus, amellyel gyorsan lehet rendezési szempontot és irányt váltani és amelyek azonnal frissítik a DataView vezérlőt:

  function sortBy(col)
  {
    fetchParams.orderby = col;
    dv.fetchData();
  }

  function sortAsc(dir)
  {
    fetchParams.asc = dir;
    dv.fetchData();
  }

Végül már csak UI elemekre van szükség ezeknek a függvényeknek a meghívásához:

  <a href="#" onclick="sortBy('Name')">Név szerint</a> 
  <a href="#" onclick="sortBy('Capital')">Főváros szerint</a> 
  | 
  <a href="#" onclick="sortAsc(true)">A-Z</a> 
  <a href="#" onclick="sortAsc(false)">Z-A</a>

Rakjuk össze mindezt egy oldalra és a felhasználó boldogan kattintgathat a linkekre, a háttérben a megfelelő sorrendben fognak letöltődni az adatok és azonnal meg is jelennek a böngészőben – természetesen AJAXosan frissítve az oldalnak csak az érintett részét.

A szép az egészben, hogy a tudomány nem áll meg itt: a rendszer képes arra is, hogy észrevegye, ha egy változó értéke megváltozik és automatikusan frissítse az értéket a felhasználói felületen. Folyt. köv.

A cikkhez tartozó forráskód letölthető innen.


zip CountrySample-2-Service.zip (8 kB)


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.

2009.10.04. 8:33:01 | Permalink | Hozzászólások: 0 | Tárgyszavak: , ,


  • Office 2007 ribbon ikonok

    Balássy György (MS RD, ASP.NET MVP, MCTS) Korábban a SiteSource add-in fejlesztésekor futottam bele abba a problémába, hogy kellene egy jól mutató ikon az add-inhoz tartozó szalagra. Kedvenc ikonunkat kétféle képpen lehet megjeleníteni és a Visual Studioba beépített Ribbon Designer mindkettőre ad is lehetőséget. Tovább »
  • ASP.NET AJAX 4: Content Delivery Network és ScriptManager

    Balássy György (MS RD, ASP.NET MVP, MCTS) Korábban már említettem, hogy a Ajax Library-hez tartozó JavaScript fájlokat a Microsoft közzétette a saját Content Delivery Networkjén. Ráadásul nem csak az Ajax Library split script fájljai és a jQuery Library, hanem a System.Web szerelvényben található hagyományos WebForms szkriptek is felkerülnek a CDN-re. Mindez felturbózva a ScriptManager új lehetőségeivel teljesen szabályozhatóvá teszi, hogy pontosan milyen szkript hivatkozások renderelődnek az oldalunkba. 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