jQuery címkéhez tartozó bejegyzések

Ajaxos fájl feltöltés

Időnként felmerül, hogy jó lenne úgy feltölteni egy fájlt, hogy közben az oldal többi része nem változik, magyarul Ajaxosan. Rossz hírem van, az XMLHttpRequest objektum Level 1 változata ezt nem tudja, tehát ha régebbi böngészőkre is tekintettel kell lennünk, akkor nincs mese trükközni kell.

A legelterjedtebb trükközési módszer az iframe alkalmazása, azt ugyanis bátran lehet postbackelni, az egyetlen szépséghiba, hogy a válasz, például validációs hibák is az iframe-be fognak megérkezni. Tehát ha rejtett iframe-mel dolgozunk, akkor a választ onnan ki kell venni, és az oldal megfelelő részén meg kell jeleníteni. Van tehát feladat bőven, szerencsére a jQuery Form Plugin sokat tud segíteni a megvalósításban.

Először is készítsünk egy view-modelt szerver oldalon, amiben egy HttpPostedFileBase típusú tulajdonság fogja képviselni a feltöltött fájlt. Mellécsaptam még egy kötelező Name tulajdonságot, csak úgy a demonstráció kedvéért:

public class UploadVM
{
    [Required( ErrorMessage = "Please enter a name!" )]
    public string Name { get; set; }

    [Attachment]
    public HttpPostedFileBase Attachment { get; set; }
}

Az [Attachment] a korábbi cikkben bemutatott, fájl validálásra használt attribútum. Ellenőrzi, hogy van-e feltöltve fájl, illetve hogy helyes a kiterjesztése és nem túl nagy-e a mérete.

Ehhez a modellhez már készíthetünk egy űrlapot, ami fel fogja küldeni a fájlt és a megadott nevet:

@using( Html.BeginForm( "Index", "Home", FormMethod.Post, 
        new { id = "myForm", enctype = "multipart/form-data" } ) )
{
    <p>
        <label for="txtName">Name:</label>
        <input type="text" id="txtName" name="Name" />
    </p>

    <p>
        <label for="fupAttachment">File:</label>
        <input type="file" id="fupAttachment" name="Attachment" />
    </p>

    <p>
        <input type="submit" value="Upload" />
    </p>    

    <div id="errors"></div>
}

Fontos, hogy a generált formnak multipart/form-data értékű enctype attribútuma legyen, mert azzal tud csak fájl utazni, illetve létrehoztam még egy errors azonosítójú div-et is, ahol majd a hibaüzeneteket fogjuk megjeleníteni.

Ez az űrlap a HomeController Index nevű actionjére lő, amit így implementálhatunk:

[HttpPost]
public ActionResult Index( UploadVM model )
{
  if( !this.ModelState.IsValid )
  {
    string firstError = ModelState.First( m => m.Value.Errors.Any() )
                                  .Value.Errors[ 0 ].ErrorMessage;
    return this.FileUploadFailure( firstError );
  }

  // Process the file here

  string message = String.Format( "The file '{0}' is successfully uploaded.", 
                                  model.Name );
  return this.FileUploadSuccess( message );
}

Ha a view-model valamelyik tulajdonsága hibás, akkor az attribútumoknak köszönhetően a hibák bekerülnek a ModelStatebe, amit a metódus elején szokás szerint ellenőrzünk. Ha van hiba, akkor az első hibaüzenettel térünk vissza, ha nincs, akkor pedig feldolgozzuk a fájlt és egy siker üzenettel térünk vissza.

A visszatérési érték egy JSON objektum, mert ezt tudjuk kliens oldalon barátságosan feldolgozni. Csakhogy ne feledjük, hogy a válasz egy iframe-be fog beíródni, és nem minden böngésző szeret iframe-be application/json típusú tartalmat kapni. Szerencsére a jQuery Form Plugin támogatja azt a trükköt, hogy a JSON tartalmat egy <textarea> elembe ágyazva küldjük vissza a szerverre text/html típusú válaszként, onnan ő majd kiveszi a JSON tartalmat.

Hogy ez a csomagolás egyszerű legyen, készítettem egy saját result típust:

public class FileUploadJsonResult : JsonResult
{
  public override void ExecuteResult( ControllerContext context )
  {
    this.ContentType = "text/html";
    context.HttpContext.Response.Write( "<textarea>" );
    base.ExecuteResult( context );
    context.HttpContext.Response.Write( "</textarea>" );
  }
}

Az egyszerű példányosításhoz pedig két bővítő metódust, melyek közül az egyikkel sikert, a másikkal hibát lehet jelezni:

public static FileUploadJsonResult FileUploadSuccess( 
  this Controller controller, string successMessage = null )
{
  return new FileUploadJsonResult
  {
    Data = new { Success = true, Message = successMessage }
  };
}

public static FileUploadJsonResult FileUploadFailure( 
  this Controller controller, string errorMessage )
{
  return new FileUploadJsonResult
  {
    Data = new { Success = false, Message = errorMessage }
  };
}

Itt a Data tulajdonságban bármilyen szerkezetű objektumot összerakhatunk, az fog megérkezni válaszként a kliensre JSON formátumban. Itt most az egyszerűség kedvéért egy Success tulajdonságban jelzem, hogy a feltöltés hibátlanul megtörtént-e, és egy Message tulajdonságban hibaüzenetet vagy sikeres feltöltésre utaló üzenetet küldök vissza, amit a böngésző megjeleníthet.

Készen vagyunk tehát a szerver oldallal: van egy formunk, ami elPOSTolható egy actionnek, ami validálja a feltöltött tartalmat, és ha minden mező érvényes adatot tartalmaz, akkor feldolgozza őket, és az eredményt JSON válaszban jelzi.

Már csak a kliens oldal van hátra, amit természetesen a jQuery Form Plugin segítségével valósítunk meg. Ahogy a neve is mutatja, ez egy jQuery plugin, amit a form elemet burkoló jQuery objektumra (itt épp $form) kell ráhúznunk:

$form.ajaxForm({
    iframe: true,
    dataType: "json",
    beforeSubmit: function () {
      // TODO     },
    success: function (result) {
      // TODO 
    },
    error: function () {
      // TODO 
    }
});

Az alábbi eseménykezelőket célszerű megvalósítanunk:

  • beforeSubmit: ez a POST elküldése előtt fut le, itt írhatjuk ki például, hogy a feltöltés folyamatban van, vagy például a jQuery BlockUI plugin segítségével letilthatjuk az űrlapon lévő vezérlőket.
  • success: ez akkor hívódik meg, ha látszólag hibátlan volt a feltöltés, bár tapasztalatom szerint akkor is meg tud hívódni, ha a szerver valamilyen hibát jelez. Ha nem volt hiba, akkor a paraméterül kapott változóban a szerverről visszaküldött JSON objektum jelenik meg, de számítsunk rá, hogy hiba esetén ez lehet undefined is!
  • error: hiba esetén ez fut le.

Íme egy példa a success callback implementálására:

if (!result) {
$errors.html('<div class="validation-summary-errors"><ul><li>Oooops....
                </li></ul></div>');
}
else {
  $form.resetForm();

  if (result.Success === true) {
    var message = result.Message;
    if (message && message.length > 0) {
      $errors.html( message );
    }
  }
  else {
    $errors.html('<div class="validation-summary-errors"><ul><li>{0}
                  </li></ul></div>'.format(result.Message));
  }
}

Ebben a kódban a hibák megjelenítését egy kicsit összetett HTML darabkával végezzük. Ennek az a jelentősége, hogy a klasszikus ASP.NET MVC-s validálás is pont ilyen HTML-t generál magából, tehát a mi Ajaxos hibáink is pont ugyanolyan stílussal fognak megjelenni.

A format egy a szerver oldali String.Formathoz hasonló függvény, amit például így implementálhatunk JavaScriptben:

String.prototype.format = function () {
  var args = arguments;
  return this.replace(/\{\{|\}\}|\{(\d+)\}/g, function (m, n) {
    if (m === "{{") { return "{"; }
    if (m === "}}") { return "}"; }
    return args[n];
  });
};

Ha a szerverről nem csak az első, hanem összes ModelState hibát visszaadnánk, akkor egy ciklusban renderelhetnénk ki őket.

A cikkhez tartozó forráskód rengeteg kommenttel letölthető innen: http://sdrv.ms/10QQLSp

 

Technorati-címkék: ,
Reklámok

A jQuery szakít a régi IE verziókkal

jquery-logoMa megjelent a jQuery legújabb, 1.9 verziója és vele együtt a 2.0 verzió bétája. Bár a két verziónak ugyanaz az API-ja (pár dolgot az 1.9-ből éppúgy kivettek, mint a 2.0-ból), mégis óriási különbség van közöttük:

  • Az 1.9 verzió – a korábbiakhoz hasonlóan – fut Internet Explorer 6, 7 és 8 verziókon, ahogy ők mondják “oldIE”-n.
  • A 2.0 nem fog futni oldIE-n. Ez számos egyszerűsítést tett lehetővé, aminek köszönhetően a 2.0 verzió gyorsabb és kisebb lesz, mint az 1.9 verzió.

A Release Notes szerint a fejlesztők mindkét verziót támogatni fogják a jövőben, de én úgy sejtem, hogy ahogy az lenni szokott, ez nem lesz mindig így. Előbb-utóbb az 1.9 el fog avulni, az új funkciók pedig könnyen lehet, hogy csak a 2.0 verzióba fognak bekerülni.

Vajon ez kinek rosszabb, az IE-nek vagy a jQuery-nek? A fejlesztők fognak átállni a jQuery-ről más könyvtárra, vagy a weboldalak fognak lemondani a régi Internet Explorer támogatásáról?

 

Technorati-címkék: ,,

jQueryUI Datepicker lokalizálás

A jQueryUI Datepicker minden szempontból annyira praktikus, hogy már szinte minden projektünkben használjuk. Az eredetileg angol nyelven megjelenő naptár vezérlőt nagyon könnyen lehet más nyelvűvé alakítani, mindössze az adott nyelvhez tartozó lokalizációs fájlt kell betöltenünk az oldalunkra, majd át kell kapcsolnunk rá a Datepickert:

$(selector).datepicker($.datepicker.regional['hu']);

De mi van akkor, ha az oldal renderelésekor még nem tudjuk, hogy milyen nyelvre lesz szükségünk? Ilyenkor jöhetnek a dinamikus szkript betöltési módszerek a kb. 1KB-os nyelvi fájlok betöltésére.

Ha sokszor, sokféle nyelven használjuk a dátum vezérlőt, akkor hasznos lehet a kis méretű fájlok külön-külön letöltése helyett egyszerre letölteni az összes nyelv beállításait. Ezen az URL-en található egy ilyen fájl, amiben az összes (?) támogatott nyelv beállításai megtalálhatók:

http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/i18n/jquery-ui-i18n.min.js

Ez egy minimalizált fájl, de a mérete még így is 51KB, azonban ha a webszerveren beállítjuk a tömörítést, akkor mindössze 11KB marad.

 

Technorati-címkék: ,,

Ajax hívásnál 401 Unauthorized

Érdekes hibával találkoztam a héten. Adott egy jQuery-vel meghívott WebMethod, ahonnan a HTTP kérések kiválóan kimennek, de a válasz mindig ez:

{ "Message":"Authentication failed.",
  "StackTrace":null,
  "ExceptionType":"System.InvalidOperationException" }

Különlegességként a válaszban még érkezik egy jsonerror: true fejléc sor is.

Amit ilyenkor célszerű ellenőrizni:

  • Jogosultságok a web.configban ne tiltsák a hozzáférést.
  • Ha esetleg kell Session is, akkor a szerver oldalon a WebMethod attribútumnál legyen beállítva az EnableSession=true tulajdonság.
  • Ha a szerver oldali metódus ASPX-ben van, akkor legyen static.
  • És a ráadás: az ASMX fájlban lévő @WebService direktíva Class tulajdonsága az .ASMX.CS fájlban lévő névtérre és osztályra mutasson. Ez utóbbi azért huncut, mert a Solution Explorerben az .asmx fájlra kattintva az .asmx.cs nyílik meg, nincs fordítási hibaüzenet és a futás idejű hibából sem derül ki, hogy ez a gond.

 

Technorati-címkék: ,,,,

JavaScript hibakeresés 1×1

Véleményem szerint ma már nem létezik “szerver oldali webprogramozó”, hiszen szinte minden weboldalhoz tartozik már szerver és kliens oldali logika is. A kliens oldali JavaScript és jQuery kódok debuggolása elsőre nagyon idegen feladatnak tűnhet, de valójában egyáltalán nem ördöngösség és szerencsére már kiváló eszközök is vannak hozzá. Az alábbi videóban a Firebug, a FireQuery és a Visual Studio 2010 JavaScript debuggolási lehetőségei közül a leggyakrabban használtak kerülnek terítékre:

Teljes képernyős nézet, 720p felbontás ajánlott.

 

ASP.NET MVC remote validation

A model validation az egyik kedvencem az ASP.NET MVC-ben. Egy helyre kerül minden, ami a validáláshoz kell, ráadásul a jQuery validationnek köszönhetően a beépített “validátorok” nagyon jól működnek kliens oldalon is.

Legyen mondjuk egy klasszikus Person modell osztályunk, amire könnyen felaggathatom a validálási szabályokat leíró attribútumokat:

public class Person
{
    [DisplayName( "E-mail cím:" )]
    [Required( ErrorMessage = "Az e-mail cím megadása kötelező! ")]
    public string Email { get; set; }

    [DisplayName( "Felhasználónév:" )]
    [Required( ErrorMessage = "A felhasználónév megadása kötelező! " )]
    public string UserName { get; set; }

    [DisplayName( "Jelszó:" )]
    [Required( ErrorMessage = "A jelszó megadása kötelező! " )]
    public string Password { get; set; }
}

A view-ba pedig csak @Html.ValidationMessageFor hívások kellenek a hibaüzenetek megjelenítéséhez (amiket egyébként a VS le is generál magától):

@using( Html.BeginForm() )
{
    @Html.ValidationSummary( true )
    <fieldset>
        <legend>Regisztráció</legend>
        <div class="editor-label">
            @Html.LabelFor( model => model.Email )
        </div>
        <div class="editor-field">
            @Html.EditorFor( model => model.Email )
            @Html.ValidationMessageFor( model => model.Email )
        </div>
        <div class="editor-label">
            @Html.LabelFor( model => model.UserName )
        </div>
        <div class="editor-field">
            @Html.EditorFor( model => model.UserName )
            @Html.ValidationMessageFor( model => model.UserName )
        </div>
        <div class="editor-label">
            @Html.LabelFor( model => model.Password )
        </div>
        <div class="editor-field">
            @Html.EditorFor( model => model.Password )
            @Html.ValidationMessageFor( model => model.Password )
        </div>
        <p>
            <input type="submit" value="Mehet" />
        </p>
    </fieldset>
}

A helyzet akkor kezd bonyolódni, amikor kliens oldalon szeretnénk validálni, de az input ellenőrzési logika vagy a hozzá szükséges egyéb adatok szerver oldalon vannak, például egy adatbázisban. Még kellemetlenebb a helyzet, ha ráadásul nem is egyetlen mező értékét kell ellenőriznünk, hanem több adat együttállását kell vizsgálnunk. Ezt megoldhatnánk egy postback után a controllerben, de sokkal felhasználóbarátabb, ha Ajaxosan oldjuk meg, hiszen így már az űrlap kitöltése közben tudjuk figyelmeztetni a felhasználót, hogy javítsa ki a beírt értékeket. Szerencsére erre a problémára van közvetlen megoldás az ASP.NET MVC-ben, úgy hívják, hogy remote validation. Így kell beizzítani:

A modellben adjunk egy Remote attribútumot a validálandó mezőhöz:

[Remote( "ValidateUserNameAndEmail", "Home", AdditionalFields = "Email" )]
public string UserName { get; set; }

Itt meg kell adnunk, hogy melyik controller action lesz az Ajax hívás szerver oldali végpontja. Ha több mező értékére van szükségünk szerver oldalon, akkor használhatjuk az AdditionalFields paramétert. A fenti példában a validálás akkor fog megtörténni, amikor a UserName mező értéke megváltozik és a szerverhez el fog jutni az Email mező értéke is, az esetleges hibaüzenet pedig a UserName mező mellett fog megjelenni. Szerencsére semmi akadálya annak, hogy ugyanezt az attribútumot ráakasszuk az Email mezőre is, AdditionParameterkent a UserName mezőt adva meg.

Már csak a hivatkozott controller actiont kell megírnunk, például így:

[OutputCache( NoStore = true, Location = OutputCacheLocation.None )]
public JsonResult ValidateUserNameAndEmail( string userName, string email )
{
    return this.IsValid( userName, email ) ? 
        this.Json( true, JsonRequestBehavior.AllowGet ) : 
        this.Json( "Ezzel a névvel és e-mail címmel már létezik regisztráció!", 
            JsonRequestBehavior.AllowGet );
}

A valódi ellenőrző logikát áttettem egy IsValid függvénybe, hogy itt ne zavarjon. A lényeg:

  • Klasszikus controller action azokkal a paraméterekkel, amiket ellenőrizni szeretnénk. Ha van a modellben AdditionalFields, akkor mindet.
  • Válaszként egy JsonResult típussal kell visszatérnünk.
  • Ha az adat helyes, akkor a válasz true, ha hibás, akkor a hibaüzenet.
  • Meg kell adni a JsonRequestBehavior.AllowGet paramétert, anélkül nem fog menni.
  • Célszerű az OutputCache-t kikapcsolni, hogy a böngésző ne gyorsítótárazza a választ.

A hibaüzenet a Html.ValidationMessageFor helyén fog megjelenni, tehát a view-n nem kell változtatnunk. Ha nem a Studio generálta a markupot, hanem mi írtuk, akkor arra érdemes figyelni, hogy legyen benne Html.BeginForm, mezei <form> elemre tapasztalataim szerint nem működik.

Mindössze ennyi, az Ajaxos bűvészkedést az ASP.NET megcsinálja helyettünk. Íme az eredmény:

aspnet-mvc-remote-validation

Akit szeretné lerántani a leplet a varázslatról, az nézze meg a generált markupban a data-val-remote- attribútumokat és figyelje meg a HTTP forgalmat például Fiddlerrel. Érdemes!

 

Technorati-címkék: ,,,,,

Golyóálló Ajax hívások

Korábban írtam már arról, hogy nagyon egyszerűen tudunk ASP.NET-es page method-okat hívni jQuery segítségével. No, de mi van akkor, ha valamilyen nem várt hiba történik közben?

Nézzük lépésről lépésre, kezdjük először azzal, hogy hogyan is megy ez. Először is legyen egy link, ami elindítja az Ajax hívást, és egy span, ami majd megjeleníti az eredményt:

  <a href="#" id="simpleLink">Egyszerű Ajax hívás</a>
  <span id="result"></span>

Legyen egy WebMethod az oldalon belül, amit ajaxosan meg akarunk hívni a linkre kattintáskor:

  [WebMethod]
  public static string SayHello( string name )
  {
    return "Hello " + name;
  }

Az Ajax híváshoz persze jQuery-t használunk, szerencsére így nagyon rövid a JavaScript kód:

  $("#simpleLink").click(function (e) {
    e.preventDefault();

    $.ajax({
      type: "POST",
      url: "Default.aspx/SayHello",
      data: "{ 'name':'World' }",
      dataType: "json",
      contentType: "application/json; charset=utf-8",
      success: function (data) {
        $("#result").html(data.d);
      }
    });
  });

Hol lehet ezzel probléma? Néhány tipikus eset:

  • Bármiféle alacsonyszintű (hálózati) hiba keletkezik.
  • A szerver oldali kódból kivétel röppen a kliensre.
  • Lejár a felhasználó login sessionje, ezért az Ajax hívás authentikációs hibával száll el, mert nem jut el a szerver oldali végpontig.
  • Lejár a felhasználó munkamenete, ezért a szerver oldali kód érvénytelen Session értékekkel dolgozik.

Ezek között van könnyebb és nehezebb eset. Az alacsonyszintű hibákat lehet kezelni egy error callbackben kliens oldalon, szerencsére a jQuery támogatja.

A szerver oldalon keletkező kivétel már rosszabb, mert ennyire barátságos válaszból kell dolgoznia a kliensnek, ami egy HTTP 500 Internal Server Error társaságában jön vissza:

  {
    "Message":"Baj van!",
    "StackTrace":"   at _Default.SayHello(String name) 
       in w:\\System\\Desktop\\AjaxWrapperSample\\Default.aspx.cs:line 14",
    "ExceptionType":"System.InvalidOperationException"
  }

A példában itt egy “nem várt” eset szerepel (hiszen az InvalidOperationException általában erre utal), de mihez kezdünk akkor, ha az üzleti logikánk is kivétellel jelzi, ha valamit nem sikerült végrehajtani? Például mert a felhasználónak nincs hozzá jogosultsága, vagy megváltozott az üzleti objektum állapota, karbantartás alatt van az alkalmazásszerver stb.

A lejárt login session kifejezetten kellemetlen, mert klasszikus HTTP 200 OK tud visszajönni, csak éppen a tartalomban nem a kért adatokat küldi vissza a szerver, hanem a bejelentkező oldalunk HTML markupját. Talán erre számít legkevésbé az ember.

Ezeket természetesen mind lehet kezelni szerver és kliens oldalon is, a nehézséget az jelenti, hogy ezt minden egyes Ajax hívásnál meg kell tennünk kliens és szerver oldalon is. Célszerű lenne olyan megoldást találnunk, ami nem igényli az összes WebMethodunk és az összes kliens oldali hívásunk szétbarmolását, hanem központilag tudjuk valahogy kezelni a hibákat. És itt jön be a képbe az a szemérmetlenül kellemetlen tény, hogy Ajax hívások esetén az ASP.NET klasszikus központi eseménykezelői (pl. Application_Error) nem hívódnak meg…

Az alábbi megoldást az egyik projektünkben használjuk és eddig bevált. A módszer lényege, hogy az eredeti kódot becsomagoljuk és a csomagolás feladata a részletek elrejtése mind kliens, mind szerver oldalon.

Első lépésként definiáltuk az alábbi osztályt:

  public class AjaxResult<TResult>
  {
    public bool Success { get; set; }
    public TResult Value { get; set; }
    public string Error { get; set; }
  }

Ennek az osztálynak a feladata, hogy burkolja az eredeti választ a Value paraméterben és további információkat csapjon hozzá, amit a kliens felhasználhat az egyedi hibakezeléshez. Itt a példában csak két paramétert vettem fel, a Success jelzi, ha a hívás szerver oldalon nem okozott kivételt, az Error pedig az esetleges hibaüzenetet (ezeket persze lehetne egyben is, de a bool és a string külön nekem szimpatikusabb).

A következő feladat a szerver oldali csomagolás elkészítése olyan módon, hogy az eredeti kódra a legkisebb hatással legyen. Erre az alábbi megoldás született:

  public static class AjaxWrapper
  {
    public static AjaxResult<TResult> Execute<TResult>( Func<TResult> body )
    {
      try
      {
        // Inicializálás, szerver konfigurálás itt...

        return new AjaxResult<TResult>
        {
          Success = true, 
          Value = body()
        };
      }
      catch( Exception ex )
      {
        return new AjaxResult<TResult>
        {
          Success = false,
          Error = ex.GetType().Name
        };
      }
    }
  } 

Oké, a Func miatt elsőre talán nem egyértelmű, hogy mi történik, ezért gyorsan megmutatom, hogyan kell használni és máris világos lesz a jelentése. A fenti SayHello metódusból ez lett:

  [WebMethod]
  public static AjaxResult<string> SayHelloSafe( string name )
  {
    return AjaxWrapper.Execute( () =>
    {
      return "Hello " + name;
    });
  }

A kód lényegi része tehát megmaradt, mindössze egy AjaxWrapper.Execute hívást kell köré csapni. Siker esetén a lényegi rész eredménye bekerül a Value tulajdonságba, hiba esetén pedig a kivétel típusa kerül az Error tulajdonságba. Ezzel elértük azt, hogy a kódunkban keletkező összes szerver oldali hibát elkapjuk és barátságos formában juttatjuk a kliensre.

Már csak ki kell csomagolnunk a választ kliens oldalon, amivel egyúttal a klasszikus d tulajdonságtól is megszabadulhatunk. Ehhez jó lesz az alábbi JavaScript függvény:

  function myAjax( url, params, successCallback, errorCallback ) {
    $.ajax({
      type: "POST",
      url: url,
      data: params,
      dataType: "json",
      contentType: "application/json; charset=utf-8",
      success: function (response, status, xhr) {
        if (response.d.Success) {
          successCallback(response.d.Value, status, xhr);
        }
        else {
          errorCallback(response.d.Error, status, xhr);
        }
      },
      error: function (xhr, status, error) {
        if (xhr.status === 401) {
          alert("Lejárt a munkameneted, lépj be újra!");
          window.location.href = "Login.aspx";
          return;
        }

        errorCallback(xhr, status, error);
      }
    });            
  }

Itt egyúttal megoldhatjuk a lejárt login session esetét is. Ha szerver oldalon az AjaxWrapper.Execute metódusban kitalálunk egy módszert a lejárt Session kezelésére, akkor ezt az esetet is kezelhetjük itt központilag.

Végezetül csak arra kell figyelnünk, hogy mostantól a $ajax helyett mindenhol ezt a myAjax függvényt használjuk:

  myAjax(
    "Default.aspx/SayHelloSafe",
    "{ 'name':'World' }",
    function (response) {
        $("#result").html(response);
    },
    function (response) {
        $("#result").html('Gáz van: ' + response);
    }
  );

Kicsit egyszerűsítettem a kódon, élesben egy kicsit bonyolultabb, de ez a lényeg. A teljes forráskód letölthető az MSDN Kompetencia Központ oldaláról.

Ti hogyan kezelitek ezeket a kivételesen kellemetlen eseteket?

 

Technorati-címkék: ,,,,