我记录网站综合系统 -- 技术原理解析[8:ActionChecker流程]
时间:2011-06-16 来源:magicDict
wojilu.Web.Mvc.CoreHandler.ProcessRequest - >
wojilu.Web.Mvc.CoreHandler.ProcessRequest: ProcessContext.Begin ->
RouteProcess InitContextProcessActionMethodChecker
ForbiddenActionChecker
LoginActionChecker
上次我们说到了初始化上下文,到了这里我们拿到的信息有
1.路由信息
2.Controller信息。
接下来我们要取得Action方法的信息了。
internal class ActionMethodChecker : ProcessorBase {
public override void Process( ProcessContext context ) {
MvcEventPublisher.Instance.BeginCheckActionMethod( context.ctx );
if (context.ctx.utils.isSkipCurrentProcessor()) return;
MvcContext ctx = context.ctx;
MethodInfo actionMethod = ctx.controller.utils.getMethod( ctx.route.action );
if (actionMethod == null) {
ctx.web.ResponseStatus( HttpStatus.NotFound_404 );
context.endMsgByView( lang.get( "exActionNotFound" ) );
}
else {
//context.setActionMethod( actionMethod );
context.ctx.setActionMethodInfo( actionMethod );
}
}
}
这个方法的大体框架大家都很熟悉了,通知系统的侦听者处理启动了。找到Action的MethodInfo的话,加入上下文里面,找不到的话,直接结束流程。为什么我们需要MethodInfo呢,我们需要的MethodInfo的一些特性信息,就是C#里面,写在方法前面的方括号[]里面的东西。我们需要知道方法的特性来做一些检查。
ForbiddenActionChecker:
这个过程我们使用了上一个步骤的结果MethodInfo。
我们检查一下它的特性里面有没有NonVisitAttribute特性。
1 public override void Process( ProcessContext context ) {2
3 MvcEventPublisher.Instance.BeginCheckForbiddenAction( context.ctx );
4 if (context.ctx.utils.isSkipCurrentProcessor()) return;
5
6 MethodInfo actionMethod = context.ctx.ActionMethodInfo; // context.getActionMethod();
7
8 Attribute forbiddenAttr = context.getController().utils.getAttribute( actionMethod, typeof( NonVisitAttribute ) );
9 if (forbiddenAttr != null) {
10 throw context.ctx.ex( HttpStatus.Forbidden_403, lang.get( "exVisitForbidden" ) );
11 }
12
13 }
NonVisitAttribute特性:
wojilu\Web\Mvc\Attr\NonVisitAttribute.cs
1 /// <summary>2 /// 当前 action 禁止直接访问,只用于代码间调用
3 /// </summary>
4 [Serializable, AttributeUsage( AttributeTargets.Method )]
5 public class NonVisitAttribute : System.Attribute {
6 }
如果一个Controller里的Method上面加了[NonVisitAttribute]的话,这个方法就没有办法被访问了。
LoginChecker:
这个过程我们同样使用了上一个步骤的结果MethodInfo。
我们检查一下它的特性里面有没有LoginAttribute 特性。
1 public override void Process( ProcessContext context ) {2
3 MvcEventPublisher.Instance.BeginCheckLoginAction( context.ctx );
4 if (context.ctx.utils.isSkipCurrentProcessor()) return;
5
6 MethodInfo actionMethod = context.ctx.ActionMethodInfo; // context.getActionMethod();
7 Attribute loginAttr = context.getController().utils.getAttribute( actionMethod, typeof( LoginAttribute ) );
8
9 if (loginAttr != null && context.IsUserLogin() == false) {
10 throw context.ctx.ex( HttpStatus.Unauthorized_401, lang.get( "exPlsLogin" ) );
11 }
12
13 }
wojilu\Web\Mvc\Attr\LoginAttribute .cs
2 /// 必须登录才能访问当前 action
3 /// </summary>
4 [Serializable, AttributeUsage( AttributeTargets.Method )]
5 public class LoginAttribute : System.Attribute {
6 }
这个特性也很容易理解,有一些功能是针对已经登入的用户才有效的,这个标签就可以验证用户是否已经登入,如果用户没有登入,这个action无法访问。一般来说,action的入口应该对于非登入用户来说是不可见的,不过可能一些action直接由地址栏的URL触发,为了屏蔽这些action的访问,加入了这个验证。
到这里为止,action的验证,一半已经结束了,另一半的验证将在下一篇中介绍。
wojilu案例介绍及赏析:[不是为了这个网站打广告,只是wojilu案例介绍,请编辑不要误会]
http://www.wojilu.com/
我记录百度百科:http://baike.baidu.com/view/5898394.htm
欢迎大家加入我记录开发团队