Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I redirect to an index action, but remove "Index/" from the url?

I am currently trying to redirect to the Index of one controller (the Company controller) from a second controller (the Search controller). In my Search controller, I have the following code:

RedirectToAction("Index", "Company", new { id = redirectTo.Id, fromSearch = true, fromSearchQuery = q })

But unfortunately, this takes me to:

/Company/Index/{id}?fromSearch=true&fromSearchQuery={q}

Where fromSearch and fromSearchQuery are optional parameters that are not always used.

Is there a way to either directly get the URL from RedirectToAction so I can encase it in a Redirect after I chop out the Index part of the string, or set up routes with the optional parameters?

like image 826
Phil Barresi Avatar asked Sep 08 '13 03:09

Phil Barresi


2 Answers

If you want just the URL you can use the Url.Action helper which takes all the same parameters but just returns the URL.

However, creating routes with optional segments followed by additional segments is more difficult because omitting a segment in the middle will just cause all the other segments to shift down and you'll wind up with your id taking the place of your action. The solution is to create a route that matches the number of segments, and position of the segments, when the optional value is omitted. You can also use route constraints to further restrict what the route matches.

For example, you could create this route:

routes.MapRoute(
    name: "IndexSearch",
    url: "{controller}/{id}",
    defaults: new { action = "Index" },
    constraints: new { action = "Index" }
);

Coupled with the default route after it:

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

Would result in the helper call:

RedirectToAction("Index", "Company", new { id = redirectTo.Id, fromSearch = true, fromSearchQuery = q })

Creating the URL: /Company/{id}/?fromSearch=true&fromSearchQuery=q when the action is Index or the action is omitted. If the action is provided and is something other than Index than routing will defer to the default route.

like image 146
asymptoticFault Avatar answered Oct 02 '22 08:10

asymptoticFault


You need to route your request properly because you're providing search parameters as query string. Just have one search route as below:

routes.MapRoute(
    "CompanySearch",
    "Company/{id}",
    new { controller = "Company", action = "Index" }
);

Then write this controller action

public ActionResult Index(bool fromSearch, string fromSearchQuery)
{
    // do other stuff
}

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 bool FromSearch { get; set; }
    public string FromSearchQuery { 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:

http://domain.com/Company/{id}?FromSearch=true&fromSearchQuery=search+text
like image 21
Bhushan Firake Avatar answered Oct 02 '22 09:10

Bhushan Firake