allBlogsList

Custom Item Resolver and the Hidden Query String

Have you ever tried to troubleshoot an instance where a URL looks something like /ILike/Pizza , but when you drilled down to it in the content tree, there is no “Pizza” under the “ILike” item?  Don’t panic!  Your pizza will be found!  More than likely you are working with a custom item resolver.  In other words there is a class somewhere else that is interpreting “Pizza” as its own value and sending it back as a query string.  The user sees /Ilike/Pizza but your code will see /Ilike?myval=Pizza .

A custom item resolver will be a class that will inherit from the HTTPRequestProcessor and is added to the pipeline as something like this:

Here are the guts of the class

public class ILikeItemResolver : HttpRequestProcessor
    {
        public override void Process(HttpRequestArgs args)
        {
            Assert.ArgumentNotNull(args, "args");
            if (((Context.Item == null) && (Context.Database != null)) && !string.IsNullOrWhiteSpace(args.Url.ItemPath))
            {
                string qsValue = string.Empty;
                string decodedItemName = MainUtil.DecodeName(args.Url.ItemPath);

                string myVal = ResolveBlogItemPath(decodedItemName, "{0}/ILike/{1}", out qsValue);
                
                if (!string.IsNullOrEmpty(myVal))
                {
                    if (myVal != null)
                    {
                        NameValueCollection nv = StringUtil.ParseNameValueCollection(args.Url.QueryString, '&', '=');
                        nv.Add("myval", qsValue);
                        
                        args.Url.QueryString = StringUtil.NameValuesToString(nv, "&");
                    }
                }
            }
        }

        private string ResolveBlogItemPath(string decodedItemName, string urlPattern, out string qsValue)
        {
            qsValue = string.Empty;
            try
            {
                string pattern = urlPattern.FormatWith(@"(^.+)", @"(.+)/$");
                Match match = Regex.Match(StringUtil.EnsurePostfix('/', decodedItemName), @pattern, RegexOptions.IgnoreCase);

                if (match.Success)
                {
                    qsValue = WebUtil.UrlEncode(match.Groups[2].Value);
                    return match.Groups[1].Value;
                }

            }
            catch (Exception ex)
            {
                Log.Error("ILikeItemResolver failed to resolve!", ex, new object());
            }
            return string.Empty;
        }
    }


Here is what the class does:

  1. Gathers the current HttpRequestargs item path.
  2. Attempts to match that path against our string of “{0}/ILike/{1}”.
  3. If a match is found the value on the right is returned.  In our instance that would be “Pizza”.
  4. Finally that value is added to our NameValueCollection and returned as part of the query string.

From here I would probably search for the Pizza item in my data folder, maybe call a web service with it, or just use the value as string.  You could also consider extending the logic in your class to do the item or service call automatically.  I would take it as a case by case scenario.