Resumé

UrlRewrite vs ASP.Net 3.5 DataPager

Cristian Merighi () 5,00

I fields del nuovo controllo per ASP.Net 3.5 non sembrano andare d'accordo con la riscrittura degli URL. Ecco una possibile soluzione.
Questo articolo è da considerarsi obsoleto. Alcune funzionalità potrebbero non essere più disponibili e non è possibile aggiungere commenti.

ASP.Net 3.5 ha portato (pochi) nuovi controlli che promettono di essere di notevole aiuto per addolcire il conflitto che da anni esiste tra la tecnologia WebControls-based e gli aspetti di correttezza formale XHTML/CSS e di Search Engine Optimization.
Adoro il ListView ovviamente, ma apprezzo forse di più il DataPager che posso associarvi.

Infatti, valorizzando la propretà QueryStringField dello stesso, posso finalmente dimenticami degli odiosi links javascript dei pager controls passati (illeggibili per i search-bots)!

Bene, tutto a posto allora: ho questi nuovi oggettini, scrivo il mio ultra-hackabile-leggibile-SEOttimizzato website che è una bomb... whoops!
I Fields del mio DataPager puntano alla pagina fisica e non a quella virtuale?! Sul serio?...
Proprio così :(

Vabbè, magari utilizzo un ControlAdapter custom e risolvo agevolmente il problema.
No-no.

Vabbè, allora prendo - ad esempio - il NumericPagerField, che non è marcato sealed, lo subclasso e sostituisco con un bell'override il metodo incriminato.
No-no... o almeno, non così facilmente...

Diamo un occhio - grazie Reflector - alla catenaria di classi e metodi che si avvicendano per la renderizzazione dei nostri link di paginazione:
NumericPagerField espone un metodo virtual (CreateDataPagers) che dà inizio a tutto il processo.
Esso "stuzzica" due subroutines private CreateNextPrevLink e CreateNumericLink (i nomi sono autoesplicativi direi) le quali a loro volta attingono ad un metodo GetQueryStringNavigateUrl appartenente alla classe base abstract DataPagerField e che è marcato protected (non virtual)!

Reflector > NumericPagerField > CreateNumericLink method

Qui non colgo il senso dell'architettura: perché un metodo protected ed, al contempo, una chiamata esplicita e blindata da una classe derivata alla versione base del metodo stesso?!

Per ovviare a questo inconveniente si rende necessario scrivere più codice di quanto pensassi...
Di seguito riporto quello che è il metodo centrale da riscrivere, per far funzionare questa sottoclasse di NumericPagerField in abbinamento con la riscrittura degli URL è però necessario ulteriore, verboso, codice (disponibile nella sua interezza più sotto):

protected new string GetQueryStringNavigateUrl(int pageNumber)

        {

            string queryStringField = this.DataPager.QueryStringField;

            StringBuilder builder = new StringBuilder();

            HttpRequest request = this.DataPager.Page.Request;

            string url = request.RawUrl;

            int qMarkNdx = url.IndexOf("?");

            if (qMarkNdx > -1) url = url.Substring(0, qMarkNdx);

            builder.Append(url);

            builder.Append("?");

            foreach (string str2 in request.QueryString.AllKeys)

            {

                if (string.IsNullOrEmpty(str2) || str2.Equals(DataPager.QueryStringField, StringComparison.InvariantCultureIgnoreCase)) continue;

                builder.Append(HttpUtility.UrlEncode(str2));

                builder.Append("=");

                builder.Append(HttpUtility.UrlEncode(request.QueryString[str2]));

                builder.Append("&");

            }

            builder.Append(queryStringField);

            builder.Append("=");

            return (builder.ToString() + pageNumber.ToString(System.Globalization.CultureInfo.InvariantCulture));

        }

 

Di seguito il codice scaricabile.

zip file « UrlRewriteNumericPagerField class (C#)

Take care. Bye.

Feedbacks

  • Re: UrlRewrite vs ASP.Net 3.5 DataPager

    Steve domenica 22 marzo 2009 0,00

    I recently ran into this problem as well. Cristian.. Can you describe how one would hook up the code that you provided? Thanks

  • Re: UrlRewrite vs ASP.Net 3.5 DataPager

    Chad mercoledì 29 luglio 2009 5,00

    Steve, Add this to your web.config <pages> <tagMapping> <add tagType="System.Web.UI.WebControls.NumericPagerField" mappedTagType="Ryoushin.WebControls.RewriteNumericPagerField"/> </tagMapping> </pages> That will automatically map his class to your datapager controls that use the NumericPagerField

  • Crashes on null keys and adds incorrect querystring fields

    Jeff sabato 3 ottobre 2009 0,00

    ex url "host.com/products/tables/?a=1&" has a null key at the end that is not handled. ex url "host.com/products/tables/" could be re-written as "host.com/products.aspx?cat=tables" and this code would product links like "host.com/products/tables/?cat=tables&page=2" and is incorrect. This is because the code isn't parsing querystring fields from the RawUrl. Replace the "foreach (string str2 in request.QueryString.AllKeys)" block with this: System.Text.RegularExpressions.MatchCollection matches = System.Text.RegularExpressions.Regex.Matches(request.RawUrl, @"(\?|&)(?<key>[^=]+)=(?<value>[^&]+)"); foreach (System.Text.RegularExpressions.Match m in matches) { string key = m.Groups["key"].Value; string value = m.Groups["value"].Value; if (key == null || key.Equals(queryStringField, StringComparison.InvariantCultureIgnoreCase)) { continue; } builder.Append(HttpUtility.UrlEncode(key)); builder.Append("="); builder.Append(HttpUtility.UrlEncode(request.QueryString[value])); builder.Append("&"); }

  • flubbed it

    Jeff sabato 3 ottobre 2009 0,00

    Sorry, should be "builder.Append(HttpUtility.UrlEncode(value));"

  • Re: UrlRewrite vs ASP.Net 3.5 DataPager

    CMerighi lunedì 5 ottobre 2009 0,00

    @Jeff<br />Thanks for the corrections! The null key wasn't handled at all, shame on me (sample code fixed)...<br />About the QueryString issue, your implementation takes care of Routing Modules that send informations to the physical pages using querystrings and that closes the circle.<br />Personally, I tend to exploit Context.Items dictionary (as Dynamic Data Routing Engine does) instead of QueryString, it permits to pass complex object and doesn't have size limitations.

  • CreateNextPrevLink and CreateNumericLink not called

    Steve lunedì 19 ottobre 2009 0,00

    Code is hooked up and I am getting a call into the funtion "CreateDataPagers", but breakpoints in "CreateNextPrevLink" and "CreateNumericLink" are not being hit. I don't think the code is being called. Any help much appreciated. I do have the appropriate lines in web.config. Thanks, Steve

  • Re: UrlRewrite vs ASP.Net 3.5 DataPager

    micheal giovedì 19 agosto 2010 5,00

    it's very good!

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