1

不必记住用ChildActionOnly属性来装饰一堆动作方法,能够在整个控制器中指定所有方法会很方便。

尝试将ChildActionOnly属性放在控制器类上不起作用(至少在我的代码上下文中),因为在控制器的依赖注入期间,发生在请求管道的早期阶段,没有 HttpContext 或 Request 对象,并且抛出错误“请求在此上下文中不可用”。

我可以创建一个RouteConstraint使路由本身强制执行的方法ChildActionOnly吗?由于相同的请求管道问题,这似乎令人怀疑——我不知道 HttpContext 在执行 RouteConstraints 期间是否可用。如果您有想法如何实现这一点,请分享。

也许创建一个单元测试,使用反射来发现特定控制器的所有操作方法并确保它们具有ChildActionOnly属性集......

我该如何做到这一点?您能否提供一些入门代码(不必完善甚至可以工作,只是一个起点会有所帮助)。

4

2 回答 2

3

我在谷歌搜索如何自己实现这一目标时找到了这个问题和答案。
虽然这个问题专门针对 MVC4,而我的回答并不直接适用于此,但指出 MVC 5 现在支持[ChildActionOnly]在整个控制器上使用该属性似乎仍然相关,这使得以下成为可能:

namespace MyWebApp.Controllers
{
   [ChildActionOnly]
   public class MyController
   {
      //Can only be called from another action
      public ActionResult MyAction()
      {
         return View();
      }
   }
}

其中,当直接导航到http://myapp.com/MyController/MyAction时会返回以下内容:

Server Error in '/' Application.

The action 'MyAction' is accessible only by a child request. 
  Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace

有关错误的更多信息以及它起源于代码的位置。

 Exception Details: System.InvalidOperationException: The action 'MyAction' is accessible only by a child request.
于 2015-09-18T10:23:00.940 回答
0

过滤器怎么样?您可以创建自定义过滤器,然后将过滤器添加到 FilterConfig。MVC 中的过滤器允许您在执行操作之前/之后添加业务逻辑(代码),在示例中,对于操作的每个请求,它将先执行然后执行操作,您可以访问:

HttpContext.Current.Session filterContext.HttpContext.Request

你可以重定向

filterContext.Result = 新的重定向结果。

存在不同类型的过滤器: 1. 身份验证过滤器(ASP.NET MVC5 中的新功能) 2. 授权过滤器 3. 操作过滤器 4. 结果过滤器 5. 异常过滤器

在下面的示例中,我为授权创建了一个自定义过滤器

 public class CustomFilter : FilterAttribute, IAuthorizationFilter
 {
    public void OnAuthorization(AuthorizationContext filterContext)
    {

       if (!UserRepository.IsValidUserBy(HttpContext.Current.Session["userName"].ToString()))
            {
                filterContext.Result = new RedirectResult("~/User/AccessDenied", true);
            }
    }
   }

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
        filters.Add(new MyExpirePageActionFilterAttribute());
       filters.Add(new CustomFilter ());

    }
于 2014-10-01T21:59:58.983 回答