Resumé

JSON, ASP.NET Ajax e limiti di Ricorsione

Cristian Merighi () 0,00

Una breve digressione con qualche appunto relativo ad esperienze lavorative su ASP.NET Ajax, JSON e la subdola Recursion Limit Exceeded Exception.
Questo articolo è da considerarsi obsoleto. Alcune funzionalità potrebbero non essere più disponibili e non è possibile aggiungere commenti.

Ci sono tecnologie e design pattern che non posso fare a meno di utilizzare/seguire: si tratta di una questione di principio, che prescinde dalla nobiltà (ovvero dal costo) del progetto che mi vede coinvolto.
Strutturare un applicativo su, almeno, tre livelli di logica è un mio cruccio da che ho imparato ad utilizzare questo modus operandi. E quindi giù con le business entities, e tutto ciò di positivo che ne consegue (atomizzazione dei problemi, centralizzazione delle scelte, maneggevolezza di utilizzo, ...intellisense!^_^;).

Power to the client! Mi ha sempre trovato d'accordo (adoro i linguaggi di programmazione Client Side). A costo di scontrarmi con lo zoccolo duro della presa-di-posizione: quelli che preferiscono Opera a Internet Explorer e pensano di sapere tutto sui browsers... il target di ASP.NET AJAX e Silverlight si limita a tre browser principali: IE (Windows), FireFox (Windows/Mac) e Safari (Mac) ed anch'io ritengo che chiunque possa permettersi la decenza di navigare con uno dei browsers qui citati.

ASP.NET AJAX dicevo? appunto, grazie a questa sorta di Framework Client Side è possibile sfruttare allo stesso tempo una ordinata strutturazione del software e le potenzialità del proprio browser, rendendo più facile la vita allo sviluppatore e più gradevole la navigazione dell'utente.

JSON (Javascript Serialization Object Notation) è il punto d'unione tra i due elementi.

ASP.NET Ajax permette di recuperare dati Client Side tramite funzioni (PageMethods o comunque WebServices in generale) facendoseli resituire sotto forma di oggetti "complessi".

Ipotizziamo uno scenario esemplificativo schematizzato dal seguente diagramma:

class diagram

Predisponiamo ora un PageMethod per recuperare un'istanza della classe Container:

[System.Web.Script.Services.ScriptMethod, System.Web.Services.WebMethod]
public static Container GetContainerInstanceFromDB()
{
    return PacemComp.DAL.Adapter.GetRandomContainer();
}

ed ora il markup e il javascript per la pagina in questione:

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

<script type="text/javascript"/>
//<![CDATA[
    function triggerMethod(){
        PageMethods.GetContainerInstanceFromDB(onCallBackSuccess, onCallBackError);
    }
    
    function onCallBackSuccess(result, userContext, methodName){
        alert(result.DummyProperty); //please not JSON formatted result
    }
    
    function onCallBackError(error, userContext, methodName){
        if(error !== null) {
            alert(error.get_message());
        }
    }
//]]>
</script/>

Questo esempio appare piuttosto semplice e diretto, in realtà nasconde una sottile insidia:
eseguendo tale codice s'incorrerà in una exception piuttosto subdola: RecursionLimit was exceeded!

Cosa succede? Esiste un limite di ricorsione alla serializzazione degli oggetti complessi tramite JSON: esso è fissato in un valore predefinito di 100.

Piccola parentesi, tale valore può essere customizzato con una piccola modifica nel web.config:

<jsonSerialization maxJsonLength="500"
recursionLimit="1000">
<!-- converters & C... -->
</jsonSerialization>

Tornando alla Exception citata sopra, essa è dovuta al loop che viene a crearsi nel serializzatore: si parte costruendo l'object dall'istanza di Container, poi l'array di object di tipo Item e per ognuno di tali elementi di nuovo l'istanza parent Container e così via all'INFINITO...
Ciò non è consentito - ovviemante - e viene lanciata l'eccezione. Per ovviare ad essa è necessario evitare tale loop rimuovendo, ad esempio, la property "Items" dal tipo Container.

Take care. Bye.

Feedbacks

  • Re: JSON, ASP.NET Ajax and RecursionLimit Exceptions

    Rafael Miranda venerdì 6 luglio 2007 0,00

    Hi Christian... So, do you mean that I cant have a class like: public class Resource { #region Fields private string name; private Resource child; #endregion #region Properties public string Name { get { return this.name; } set { this.name = value; } } public Resource Child { get { if (this.child == null) this.child = new Resource(); return this.child; } } #endregion } Thank you!

  • Re: JSON, ASP.NET Ajax and RecursionLimit Exceptions

    CMerighi sabato 7 luglio 2007 0,00

    ...Yep (in a standard JSON scenario of course). You could expose the "Child" member as a method (a "GetChild()" one). The JavaScript Serialization process skips method members. Another <i>escamotage</i> could be the exposure of the "Child" property as a base class (let's say "ResourceBase") where only the "Name" property gets exposed. <i>public interface IWithName { string Name { get;} } public class ResourceBase : IWithName { #region IWithName Members public virtual string Name { get { return "My Name"; } } #endregion } public class Resource : ResourceBase { public IWithName Child { get { return new ResourceBase(); } } public Resource GetChild() { return new Resource(); } }</i> Hope it helps.

  • Re: JSON, ASP.NET Ajax and RecursionLimit Exceptions

    Trail Blazer lunedì 2 giugno 2008 0,00

    I've tried to add &lt;jsonSerialization maxJsonLength="500" recursionLimit="1000"> &lt;!-- converters & C... --> &lt;/jsonSerialization> but i get configuration error (Unknown section) please help

  • Re: JSON, ASP.NET Ajax and RecursionLimit Exceptions

    CMerighi lunedì 2 giugno 2008 0,00

    Hi TB, looks like you missed to declare the relevant custom section: I copied 'n' pasted the usual custom configSections node of an ASP.NET AJAX enabled website (3.5 version). As you'll see it embeds, among the others, the jsonSerialization declaration: <div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"> <p style="margin: 0px;"><span style="color: blue;">&lt;</span><span style="color: #a31515;">configSections</span><span style="color: blue;">&gt;</span></p> <p style="margin: 0px;"><span style="color: blue;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;</span><span style="color: #a31515;">sectionGroup</span><span style="color: blue;"> </span><span style="color: red;">name</span><span style="color: blue;">=</span>"<span style="color: blue;">system.web.extensions</span>"<span style="color: blue;"> </span><span style="color: red;">type</span><span style="color: blue;">=</span>"<span style="color: blue;">System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35</span>"<span style="color: blue;">&gt;</span></p> <p style="margin: 0px;"><span style="color: blue;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;</span><span style="color: #a31515;">sectionGroup</span><span style="color: blue;"> </span><span style="color: red;">name</span><span style="color: blue;">=</span>"<span style="color: blue;">scripting</span>"<span style="color: blue;"> </span><span style="color: red;">type</span><span style="color: blue;">=</span>"<span style="color: blue;">System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35</span>"<span style="color: blue;">&gt;</span></p> <p style="margin: 0px;"><span style="color: blue;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;</span><span style="color: #a31515;">section</span><span style="color: blue;"> </span><span style="color: red;">name</span

feedback
 

Syndicate

Autore

Cristian Merighi facebook twitter google+ youtube

Ultimi articoli

Top rated

Archivio

Dove sono?

Autore

Cristian Merighi facebook twitter google+ youtube

Le mie letture

Feeds