A critical vulnerability was discovered in React Server Components (Next.js). Our systems remain protected but we advise to update packages to newest version. Learn More

Anders Hattestad
Dec 23, 2009
  10464
(0 votes)

QueryRewriteProvider replace query strings with paths

For fun I tried to make a url rewriter that could translate generic query parameters to be part of the path.

So if you had a page /newlist/  and used a query parameter to get to page 2 like this /newslist/?page=2 you would get that parameter as a path like /newslist/page_2/.

The code to replace all links is simple when you base your code on FriendlyUrlRewriteProvider.

From pageRef –> Url

#region from PageRef=>URL
protected override bool ConvertToExternalInternal(UrlBuilder url, object internalObject, System.Text.Encoding toEncoding)
{
    bool status=base.ConvertToExternalInternal(url, internalObject, toEncoding);
    if (status)
    {
        PageReference pageLink = internalObject as PageReference;
        if (pageLink != null)
        {
            List<string> done = new List<string>(); 
            foreach (string key in url.QueryCollection.AllKeys) 
            {
                if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(url.QueryCollection[key]))
                {
                    url.Path += key + "_" + url.QueryCollection[key] + "/";
                    done.Add(key);
                }
            }
            foreach (string d in done)
                url.QueryCollection.Remove(d);
           
        }
    }
    return status;
}
#endregion

This code will replace all links create on a page with the path of that page and the extra “path” from the query.

FromUrl=>Page

When  want to translate the extra path to a query parameter I need to do some small changes in ConvertToInternalInternal function. But the changes are unfortantly a bit inside the base function so I needed to copy the whole function. I also needed to make some adjustments to the helper function GetPageFromStartByPath and GetPageBySegments so I could find last know page from path and get the rest of the path so I could add them to the query collection.

protected static PageReference GetPageBySegments(PageReference rootPageRef, string[] segments, string languageCode, out PageReference lastGood, List<string> segmentsRemoved)
{
    lastGood = PageReference.EmptyReference;
    for (int i = 0; (i < segments.Length) && !PageReference.IsNullOrEmpty(rootPageRef); i++)
    {
        rootPageRef = UrlSegment.GetPageBySegment(rootPageRef, segments[i], languageCode, false);
        if (!PageReference.IsNullOrEmpty(rootPageRef))
            lastGood = rootPageRef;
        else
        {
            for (int x = i; x < segments.Length; x++)
                segmentsRemoved.Add(segments[x]);
        }
    }
    return rootPageRef;
}

Inside the ConvertToInternalIntranal I added this code

if (page == null)
{
    PageReference lastGood = PageReference.EmptyReference;
    List<string> segmentsRemoved = new List<string>();
    page = GetPageFromStartByPath(str, languageBranchAndPath,out lastGood, segmentsRemoved);

    if (page == null && !PageReference.IsNullOrEmpty(lastGood) && segmentsRemoved.Count>0)
    {
        page = DataFactory.Instance.GetPage(lastGood, LanguageSelector.Fallback(ContentLanguage.PreferredCulture.Name, true));
        foreach (string segment in segmentsRemoved)
        {

            string[] parts = segment.Split('_');
            queryCollection.Add(parts[0], HttpContext.Current.Server.UrlDecode( segment.Substring(parts[0].Length + 1)));
        }
    }
}

This code basically find the depths page based on the path, and take the rest of the path’s as query parameters. The code don’t use more cpu than the ordinary friendly rewriter.

 

The full code is here

Dec 23, 2009

Comments

Mårten Berg
Mårten Berg Sep 21, 2010 10:33 AM

Works great. Thanks for sharing.

Please login to comment.
Latest blogs
A day in the life of an Optimizely OMVP - Optimizely Opal: Specialized Agents, Workflows, and Tools Explained

The AI landscape in digital experience platforms has shifted dramatically. At Opticon 2025, Optimizely unveiled the next evolution of Optimizely Op...

Graham Carr | Dec 16, 2025

Optimizely CMS - Learning by Doing: EP09 - Create Hero, Breadcrumb's and Integrate SEO : Demo

  Episode 9  is Live!! The latest installment of my  Learning by Doing: Build Series  on  Optimizely Episode 9 CMS 12  is now available on YouTube!...

Ratish | Dec 15, 2025 |

Building simple Opal tools for product search and content creation

Optimizely Opal tools make it easy for AI agents to call your APIs – in this post we’ll build a small ASP.NET host that exposes two of them: one fo...

Pär Wissmark | Dec 13, 2025 |

CMS Audiences - check all usage

Sometimes you want to check if an Audience from your CMS (former Visitor Group) has been used by which page(and which version of that page) Then yo...

Tuan Anh Hoang | Dec 12, 2025