views:

179

answers:

2

I'm trying to do something similar to what Stackoverflow is doing.

I have a quick search text box and I can put an arbitrary number of words into in and submit my search. Receiving action does this (shortened version)

public ActionResult Search(string query)
{
 Regex rx = new Regex("(?<word>[a-zA-Z0-9]+)");

 StringBuilder parts = new StringBuilder();
 foreach(Match m in rx.Matches(query))
 {
  parts.Append(parts.Length > 0 ? "+" : string.Empty);
  parts.Append(m.Groups["word"]);
 }
 return RedirectToAction("Search", new { query = parts.ToString() }); ;
}

But instead of

http://localhost/search?query=word+word

I see

http://localhost/search?query=word%2Bword

Stackoverflow does something very very similar and I'd like the do the same. I don't want my pluses escaped in my URLs. but I would still like to use RedirectToAction if possible.

A: 

I don't think you'll be able to use RedirectToAction as you would like. The issue is that it will always URL-encode your parameters.

I think you will have to handle the querystring yourself. My suggestion is to use Url.Action() to generate the base url, since it works much the same as RedirectToAction but returns a string. And then you'll have to generate the querystring yourself. Please don't forget to use Url.Encode() on each of your querystring items.

I also have an inkling that you may be able to accomplish what you'd like via a custom route. I'm not an expert on that but I saw something on using regular expressions in routes and it may be something worth looking into.

Edit: I came up with a simpler way to do what you want. Instead of manually adding the plus signs yourself, just create the full proper url with Url.Action() and then replace all %20 instances with the plus sign. Then redirct to that url. Like:

string newUrl = Url.Action("Search", new { query = query });
string plussedUrl = newUrl.Replace("%20", "+");
return new RedirectResult(plussedUrl);
PurpleFlux
Check my solution. It's even more simple and generic. I think you'll like it better than your own.
Robert Koritnik
A: 

Using action result filter

I managed to solve this by using a custom action result filter

public class UnescapePlusAttribute: FilterAttribute, IResultFilter
{
    public void OnResultExecuted(ResultExecutedContext filterContext)
    {
        if (filterContext.Result is RedirectToRouteResult)
        {
            string loc = filterContext.HttpContext.Response.RedirectLocation;
            loc = loc.Replace("%2B", "+");
            filterContext.HttpContext.Response.RedirectLocation = loc;
        }
    }
}

That's it. Decorating my Search() action method with this attribute replaced all encoded pluses with actual ones. URL is now displayed as on Stackoverflow.

Robert Koritnik