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

Re-route all requests dynamically based on some condition


I have an ASP.Net MVC 5 web site and need to dynamically re-route all incoming requests to a specific Controller and Action under certain circumstances.

For example, if the database does not exist, I would like to re-route all incoming requests to a specific Action, such as SetupController.MissingDatabase:

public class SetupController : Controller
{
    public ActionResult MissingDatabase()
    {
        return View();
    }
}

I would like to check for this condition (database existence) for each and every request. It would be best to perform the check early on in the pipeline, rather than at the top of each Action, or in each Contoller. Of course, if the incoming request is being routed to SetupController.MissingDatabase I don't need to perform the check or re-route the request.

What is the best way to accomplish this?

Specifically, where in the ASP.Net MVC 5 pipeline is the best place to perform such a check, and how would I re-route the incoming request?


Solution

  • You can create an action filter to do that and register it in the application level so that it will be executed for all the incoming requests.

    public class VerifySetupIsGood : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            var dbExists=VerifyDataBaseExists();
            if ( ! dbExists)
            {
                var values = new Dictionary<string, string> {{"action", "MissingDatabase"}, 
                                                             {"controller", "Setup"}};
    
                var routeValDict = new RouteValueDictionary(values);
                //redirect the request to MissingDatabase action method.
                context.Result = new RedirectToRouteResult(routeValDict);
            }
        }
    }
    

    Assuming VerifyDataBaseExists() executes your code to check the db exists or not and return a boolean value. Now register this action filter in the Application_Start event in global.asax.cs

    protected void Application_Start()
    {      
        //Existing code goes here
    
        GlobalFilters.Filters.Add(new VerifySetupIsGood());
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    
        //Existing code goes here
    }
    

    You can update the action filter to check for a subset of requests as well if needed. You may get the request url from the object of ActionExecutingContext and use it to do your checks.