I have two routes
routes.MapRoute(
name: "Default",
url: "{location}/{controller}/{action}/{id}",
defaults: new { controller = "Products", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Home",
url: "{controller}/{action}",
defaults: new { controller = "Home", action = "Index" }
);
When user goes to main page, he has to chose two links:
<a href="/loc1/Products/index">Location 1</a>
<a href="/loc2/Products/index">Location 2</a>
Also I have ActionFilterAttribute
, where I check for location
parameter, and if url does not have it, i redirect users to main home page.
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
string location = (string)filterContext.RouteData.Values["location"];
if (string.IsNullOrEmpty(location)
&& filterContext.ActionDescriptor.ControllerDescriptor.ControllerName != "Home"
&& !filterContext.IsChildAction)
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "controller", "Home" },
{ "action", "Index" }
});
}
SessionUtils.SetLocationName(location);
}
Based on the location
variable I will query different records from database, so when user does not provide any location in url, and tries to access Products/index/5
I want them to be redirected to the main page where they have to choose location and click one of the links.
However I get error message:
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /Products/index
How should I properly configure routes, so that users would be redirected to main page if there is no location parameter in url?
Combined all answers and especially explanations I came up with this configuration
Route configuration:
routes.MapRoute(
name: "DefaultShort",
url: "{location}/",
defaults: new { controller = "Products", action = "Index" }
);
routes.MapRoute(
name: "Default",
url: "{location}/{controller}/{action}/{id}",
defaults: new { id = UrlParameter.Optional }
);
routes.MapRoute(
name: "DefaultHome",
url: "{controller}/{action}/",
defaults: new { controller = "Home", action = "LandingPage"}
);
Some logic in OnActionExecuting
if (string.IsNullOrEmpty(location)
&& cookie != null
&& !string.IsNullOrEmpty(cookie.Values["location"])
&& filterContext.ActionDescriptor.ActionName == "LandingPage"
&& filterContext.ActionDescriptor.ControllerDescriptor.ControllerName == "Home")
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "location", cookie.Values["location"]},
{ "controller", "Measurements" },
{ "action", "Index" }
}
);
}
else if (string.IsNullOrEmpty(location)
&& filterContext.ActionDescriptor.ControllerDescriptor.ControllerName != "Home"
&& !filterContext.IsChildAction)
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "controller", "Home" },
{ "action", "LandingPage" }
}
}
If only location is provided, then it will use first route, which will redirect to the Products
controller.
The second route will be used if all three location
, controller
and action
parameters are matched in route. I have not provided default controller
and action
. This allows to use last route, when redirecting to HomeController
.
The third route will have two parameters - controller
and action
, which allows me to get to a default view in HomeController
. Using OnActionExecuting
I'm redirecting to this default view and controller if it is not pointing to a HomeController
and LandingPage
.