Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Search page MVC routing (hidden action, no slashes, like SO)

I want my searches like those in Stack Overflow (i.e. no action, no slashes):

mydomain.com/search                        --> goes to a general search page  
mydomain.com/search?type=1&q=search+text   --> goes to actual search results  

My routes:

routes.MapRoute(  
  "SearchResults",  
  "Search/{*searchType}",      --> what goes here???  
  new { action = "Results" }  
);  
routes.MapRoute(  
  "SearchIndex",  
  "Search",  
  new { action = "Index" }  
);  

My SearchController has these actions:

public ActionResult Index() { ... }  
public ActionResult Results(int searchType, string searchText) { ... }  

The search results route does not work. I don't want to use the ".../..." approach that everyone seems to be using, because a search query is not a resource, so I want the data in a query string as I've indicated, without slashes--exactly like SO does.

TIA!Matt

like image 846
Matt0 Avatar asked Feb 22 '11 08:02

Matt0


1 Answers

You don't need two routes because you're providing search parameters as query string. Just have one search route:

routes.MapRoute(
    "Search",
    "Search",
    new { controller = "Search", action = "Search" }
);

Then write this controller action

public ActionResult Search(int? type, string q)
{
    var defaultType = type.HasValue ? type.Value : 1;
    if (string.IsNullOrEmpty(q))
    {
        // perform search
    }
    // do other stuff
}

The body of this method greatly depends on the search condition whether you require both parameters when you search for stuff or just q and you have some default for type. Remember that page indexing can be done just the same way.

Using strong type parameters (validation wise)

You could of course create a class that could be validated, but property names should reflect that of the query string. So you'd either have a class:

public class SearchTerms
{
    public int? type { get; set; }
    public string q { get; set; }
}

And use the same request with equally named query variables as you do now, or have a clean class and adjust your request:

public class SearchTerms
{
    public int? Type { get; set; }
    public string Query { get; set; }
}

http://domain.com/Search?Type=1&Query=search+text
like image 174
Robert Koritnik Avatar answered Dec 08 '22 03:12

Robert Koritnik