Search code examples
c#asp.net-mvcurlquery-stringslash

Remove slash between action and querystring (like how SO's search behaves)


I've just added some search functionality to a project of mine which is working correctly. Having just used the SO search, I realised there is one tiny detail which I prefer to my own search and I became curious as to how it is achieved being as I'm also using MVC 3 and Razor for my site.

If I search SO, I'll end up with a URL such as:

http://stackoverflow.com/search?q=foo

However, searching my own application results in:

http://example.com/posts/search/?searchTerms=foo

Notice the / between search and ?. Although this is purely cosmetic, how can I remove that from the URL so it ends up as:

http://example.com/posts/search?searchTerms=foo

This is my search route:

routes.MapRoute(
    "SearchPosts",
    "posts/search/{*searchTerms}",
    new { controller = "Posts", action = "Search", searchTerms = "" }
);

I've tried removing the slash from the route but that gave an error. I also tried adding in a ? instead of the slash but that also gave an error. Would anyone be kind enough to solve this mystery for me?


Solution

  • In fact, when the searchTerms can be null-or-emptyString, that is not necessary to put it in mapRoute. And when you try to create a link by Html.ActionLink or Html.RouteLink, and pass a searchTerms parameter to it, it will create the searchTerms as a query-string without any slashes:

    routes.MapRoute(
        "SearchPosts",
        "posts/search",
        new { controller = "Posts", action = "Search"
        /* , searchTerms = "" (this is not necessary really) */ }
    );
    

    and in Razor:

    // for links:
    // @Html.RouteLink(string linkText, string routeName, object routeValues);
    @Html.RouteLink("Search", "SearchPosts", new { searchTerms = "your-search-term" });
    // on click will go to:
    // example.com/posts/search?searchTerms=your-search-term
    // by a GET command
    

    // or for forms:
    // @Html.BeginRouteForm(string routeName, FormMethod method)
    @using (Html.BeginRouteForm("SearchPosts", FormMethod.Get)) {
        @Html.TextBox("searchTerms")
        <input type="submit" value="Search" />
    
        // on submit will go to:
        // example.com/posts/search?searchTerms=*anything that may searchTerms-textbox contains*
        // by a GET command
    
    }
    

    and in controller:

    public class PostsController : Controller {
        public ActionResult Search(string searchTerms){
            if(!string.IsNullOrWhiteSpace(searchTerms)) {
                // TODO
            }
        }
    }