Search code examples
c#asp.netasp.net-mvcasp.net-routing

Asp.Net routing which redirects to homepage if url parameter is not defined


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?


Solution

  • 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.