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?
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
}
}
}