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:
- Gathers the current HttpRequestargs item path.
- Attempts to match that path against our string of {0}/ILike/{1} .
- If a match is found the value on the right is returned. In our instance that would be Pizza .
- 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.