我想知道是否有任何方法可以防止执行asp.net mvc控制器,如果在调用控制器时未满足特定条件,则使用属性?
基本上要完成的是创建类似动作过滤器的东西,但这次是在控制器初始化之前调用的控制器,并且只有在构造之前过滤器成功,否则属性过滤器应该能够将用户重定向到另一个控制器。
答案 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一样缓存任何昂贵的查找操作。