如何防止asp.net mvc控制器被实例化和执行

时间:2016-03-17 01:59:08

标签: c# asp.net asp.net-mvc-5

我想知道是否有任何方法可以防止执行asp.net mvc控制器,如果在调用控制器时未满足特定条件,则使用属性?

基本上要完成的是创建类似动作过滤器的东西,但这次是在控制器初始化之前调用的控制器,并且只有在构造之前过滤器成功,否则属性过滤器应该能够将用户重定向到另一个控制器。

1 个答案:

答案 0 :(得分:2)

如果要动态更改控制器,则可以在自定义RouteBase子类中执行此操作。重定向是一个坏主意,因为您的服务器将向客户端的浏览器发出301或302,告诉它在服务器上查找新位置。这次往返是浪费和不必要的。

public class SwitcherRoute : RouteBase
{
    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        RouteData result = null;

        // Trim the leading slash
        var path = httpContext.Request.Path.Substring(1);

        // Check that the request is what you are interested in
        if (path.Equals("home/about", StringComparison.OrdinalIgnoreCase))
        {
            result = new RouteData(this, new MvcRouteHandler());


            if (/* some (preferably cached) condition */)
            {
                result.Values["controller"] = "Home";
                result.Values["action"] = "About";
            } 
            else 
            {
                result.Values["controller"] = "Alternate";
                result.Values["action"] = "About";
            }
        }

        // IMPORTANT: Always return null if there is no match.
        // This tells .NET routing to check the next route that is registered.
        return result;
    }

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
        VirtualPathData result = null;

        var controller = Convert.ToString(values["controller"]);
        var action = Convert.ToString(values["action"]);

        if (action.Equals("About", StringComparison.OrdinalIgnoreCase))
        {
            if (controller.Equals("Home", StringComparison.OrdinalIgnoreCase) || 
                controller.Equals("Alternate", StringComparison.OrdinalIgnoreCase))
            {
                return new VirtualPathData(this, "home/about");
            }
        }

        // IMPORTANT: Always return null if there is no match.
        // This tells .NET routing to check the next route that is registered.
        return result;
    }
}

用法

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.Add(
    name: "AboutPage", 
    item: new SwitcherRoute());

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

请注意,您可以通过接受构造函数参数或甚至从内置的Route类继承来使自定义路由更加灵活。

另请注意,路由在每个请求上运行,因此您应该像this example一样缓存任何昂贵的查找操作。