软件下载 | 资讯教程 | 最近更新 | 下载排行 | 一键转帖 | 发布投稿
您的位置:最火下载站 > 网络编程 > ASP.NET > ASP.NET MVC 1.0 ControllerContext

ASP.NET MVC 1.0 ControllerContext

ASP.NET MVC 通过层层封装的上下文对象来传递执行流程所需的环境参数。

烈火网(liehuo.net)提示:点击新窗口预览!


public class ControllerContext
{
public virtual ControllerBase Controller { get; set; }
public virtual HttpContextBase HttpContext { get; set; }
public RequestContext RequestContext { get; set; }
public virtual RouteData RouteData { get; set; }
}

作为上下文的初始状态和基类,ControllerContext 包含了基本的请求信息。其中 AuthorizationContext、ExceptionContext 和 ViewContext 逻辑简单,无需花费更多的笔墨。我们真正要深入了解的是 Executing/Executed 上下文对执行流程的影响。

为了便于观察效果,我们写点测试代码来辅助我们的分析。

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
class MyActionFilterAttribute : ActionFilterAttribute
{
public string Name { get; set; }

private void Print()
{
var method = new StackFrame(1).GetMethod();
HttpContext.Current.Response.Write(String.Format("{0}.{1}<br />", this.Name, method.Name));
}

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
Print();
}

public override void OnActionExecuted(ActionExecutedContext filterContext)
{
Print();
}

public override void OnResultExecuting(ResultExecutingContext filterContext)
{
Print();
}

public override void OnResultExecuted(ResultExecutedContext filterContext)
{
Print();
}
}

public class TestController : Controller
{
[MyActionFilter(Name = "Filter1", Order = 1)]
[MyActionFilter(Name = "Filter2", Order = 2)]
[MyActionFilter(Name = "Filter3", Order = 3)]
public ActionResult Index()
{
Response.Write("Action Method! <br/>");
return Content("View Render! <br />");
}
}

顺便看看执行效果。

Filter1.OnActionExecuting
Filter2.OnActionExecuting
Filter3.OnActionExecuting

Action Method!

Filter3.OnActionExecuted
Filter2.OnActionExecuted
Filter1.OnActionExecuted

Filter1.OnResultExecuting
Filter2.OnResultExecuting
Filter3.OnResultExecuting

View Render!

Filter3.OnResultExecuted
Filter2.OnResultExecuted
Filter1.OnResultExecuted

1. ActionExecutingContext

ActionExecutingContext 中唯一有可能出 "幺蛾子" 的就是 Result 属性。

public class ActionExecutingContext : ControllerContext
{
public virtual ActionDescriptor ActionDescriptor { get; set; }
public virtual IDictionary<string, object> ActionParameters { get; set; }
public ActionResult Result { get; set; }
}

正常情况下,他会存储 Action Method 的返回结果。但注意看 ControllerActionInvoker.InvokeActionMethodFilter()。

internal static ActionExecutedContext InvokeActionMethodFilter(filter, preContext, continuation)
{
filter.OnActionExecuting(preContext);
if (preContext.Result != null)
{
return new ActionExecutedContext(preContext, preContext.ActionDescriptor,
true /* canceled */, null /* exception */)
{
Result = preContext.Result
};
}

...
}

在执行 filter.OnActionExecuting() 后,如果 preContext.Result != null,那么会终止该方法。我们知道这个方法是嵌套执行的,也就是说一旦 preContext.Result 被赋与非空值,后续的 filter 就不会被执行,包括 Action Method。试试看。

class MyActionFilterAttribute : ActionFilterAttribute
{
...

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
Print();
if (Name == "Filter2") filterContext.Result = new EmptyResult();
}

...
}

输出:
Filter1.OnActionExecuting
Filter2.OnActionExecuting

Filter1.OnActionExecuted

Filter1.OnResultExecuting
Filter2.OnResultExecuting
Filter3.OnResultExecuting

Filter3.OnResultExecuted
Filter2.OnResultExecuted
Filter1.OnResultExecuted

相关阅读
栏目导航
推荐软件