根据某些条件动态重新路由所有请求

时间:2016-01-18 19:50:38

标签: asp.net asp.net-mvc asp.net-routing

我有一个ASP.Net MVC 5网站,需要在某些情况下动态地将所有传入请求路由到特定的Controller和Action。

例如,如果数据库不存在,我想将所有传入请求重新路由到特定的Action,例如SetupController.MissingDatabase

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

我想检查每个请求的这种情况(数据库存在)。最好在管道的早期执行检查,而不是在每个Action的顶部或每个Contoller中执行检查。当然,如果传入的请求被路由到SetupController.MissingDatabase,我不需要执行检查或重新路由请求。

实现这一目标的最佳方法是什么?

具体来说,在ASP.Net MVC 5管道中哪里是执行此类检查的最佳位置,以及如何重新路由传入请求?

1 个答案:

答案 0 :(得分:0)

您可以创建一个动作过滤器来执行此操作并在应用程序级别注册它,以便为所有传入请求执行该过滤器。

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);
        }
    }
}

假设VerifyDataBaseExists()执行您的代码以检查db是否存在并返回一个布尔值。现在在global.asax.cs

中的Application_Start事件中注册此操作过滤器
protected void Application_Start()
{      
    //Existing code goes here

    GlobalFilters.Filters.Add(new VerifySetupIsGood());
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

    //Existing code goes here
}

如果需要,您可以更新操作过滤器以检查请求的子集。您可以从ActionExecutingContext的对象获取请求网址并使用它来进行检查。