繁体   English   中英

如何防止ASP.NET MVC控制器实例化和执行

[英]How to prevent an asp.net mvc controller from being instantiated and executed

我想知道是否有任何方法可以防止使用属性调用asp.net mvc控制器时调用特定的条件?

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

如果要动态更改控制器,则可以在自定义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类继承,可以使自定义路由更加灵活。

还要注意,路由会在每个请求上运行,因此您应该缓存此示例中所有昂贵的查找操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM