ActionFilterAttribute:'Cancel'属性在哪里?

时间:2010-01-26 11:48:37

标签: model-view-controller override renderaction actionfilterattribute

ActionExecutingContext上的Cancel属性发生了什么?如何在使用ActionFilterAttribute时中止RenderAction还是有另一种方法来遮蔽这只猫?

  public override void OnActionExecuting(ActionExecutingContext filterContext)
  {
   if(!filterContext.HttpContext.User.Identity.IsAuthenticated)
   {
    return;
   }
   base.OnActionExecuting(filterContext);
  }

尽管退出了OnActionExecuting操作,上面的代码仍继续执行已应用的Action?

---继续原帖: 感谢下面的答案,但是,我认为我的上下文不够清楚,我试图使以下调用无效:

<% Html.RenderAction("Menu", "Shared", new { id = Model.OtherUserId }); %>

当用户未经过身份验证时,此操作应该不返回任何内容,我可以轻松地在视图上放置“if”块,但是,我想将规则保留在控制器中。

3 个答案:

答案 0 :(得分:14)

这很有效,Mattias的结果是:

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            filterContext.Result = new EmptyResult();
            return;
        }
        base.OnActionExecuting(filterContext);
    }

答案 1 :(得分:3)

不,您无法从动作过滤器中取消渲染。有很多原因你不应该这样做。客户会看到什么?错误页面?什么?

我猜你正在构建一个授权操作过滤器,如果你没有登录,它将呈现其他内容。如果你没有登录,框架中已有一个(AuthorizeAttribute)将你重定向到登录页面。他们在框架中这样做是为了改变正在执行的结果(filterContext.Result = [[new result]];)。如果您不喜欢它的工作方式,您可以构建自己的实现。

如果您仍然需要取消渲染或类似的东西,则需要构建自己的ActionResult,并在Execute方法中执行您需要的任何逻辑。

- 更新 -

如果你想使用渲染动作,你应该把逻辑放在控制器中,如果你没有登录就返回空结果(框架中有一个名为“EmptyResult”的动作结果)。这种逻辑属于控制器动作。

答案 2 :(得分:0)

Mattias和rjarmstrong已经提出了一个问题。这是过滤器和控制器的完整代码:

public class CancelFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        //before execution
        var id = filterContext.RequestContext.HttpContext.Request.Params["id"];
        if (id == "0")
        {
            filterContext.Result = new EmptyResult();
            return;
        }
        base.OnActionExecuting(filterContext);
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        //after execution
    }
}


[CancelFilter]
public class HomeController : Controller
{
    public ActionResult DoSome(string id)
    {
        return View();
    }

    ...
}