今天继续体验发现FineUI11的变化;
本次记录一下FineUI11实现WebForms模式
的探索,解读一下WebFormsFilter
到底干了什么;
上期提到了通过属性的get
set
状态FState
实现了WebForms
的写法,今天来拆解一下的内部机制
我注意到Startup.cs
页面增加了一行代码
cs // 自定义WebForms过滤器(仅在启用EnableWebForms时有效)
options.Filters.Insert(0, new FineUICore.WebFormsFilter());
核心就是WebFormsFilter
过滤器,直接F12
F12
后发现 WebFormsFilter
继承 IPageFilter
和 IFilterMetadata
;
IPageFilter
有三个核心方法用于拦截 Razor 页面生命周期中的特定事件
方法 | 生命周期 ⏳ |
---|---|
OnPageHandlerExecuting | 页面处理开始前 |
OnPageHandlerExecuted | 页面处理结束后 |
OnPageHandlerSelected | 执行页面处理程序被选定但尚未执行之前 |
WebFormsFilter
就实现了 OnPageHandlerExecuting
和 OnPageHandlerExecuted
,一前一后;
在看具体实现前,先来做一下猜测,首先看回发的前台代码
jsF.doPostBack({
eventTarget: 'btnChangeEnable',
eventArgument: 'click',
url: '?handler=btnChangeEnable_Click',
disableControl : 'btnChangeEnable'
});
F.doPostBack
的具体实现就部看了,就是ajax,执行后的回发内容如下
通过观察参数,不难推断 OnPageHandlerExecuting
主要实现了这么几件事:
handler
找到当前页面的方法(反射),通过url
找:应该是在HttpContext.Request.Query["handler"]
里,当前页面就是context.HandlerInstance
;__FSTATE
,这里存着前台控件的状态,通过ID 或 发射 声明控件的实例并赋值,就得到了所有的控件;推测应该存到了FineUIExtensions.AllControls
__EVENTTARGET
找到当前的控件;这个有现成的方法FineUIExtensions.FindControl
其实也是AllControls
;__EVENTARGUMENT
应该也没啥用,随便放EventArgs
里就行了;与后台方法的关系如下:
1️⃣ [handler] 3️⃣[__EVENTTARGET] 4️⃣[__EVENTARGUMENT] protected void btnChangeEnable_Click(object sender, EventArgs e) { 2️⃣[__FSTATE] btnEnable.Enabled = true; btnEnable.Text = "本按钮已经启用(点击弹出对话框)"; }
以下是WebFormsFilter
反编译后的代码:
WebFormsFilterpublic void OnPageHandlerExecuting(PageHandlerExecutingContext context) { object handlerInstance = context.HandlerInstance; bool flag = context.HttpContext.Request.Method == "POST"; HandlerMethodDescriptor handlerMethod = context.HandlerMethod; if (flag && PageContext.IsFineUIAjaxPostBack() && PageManager.Instance.EnableWebForms) { A(handlerInstance); a(context, handlerInstance); MethodInfo methodInfo = A(context, handlerInstance); if (methodInfo != null) { A(context, handlerInstance, methodInfo); } } }
这里我直接写上注释,与推断基本吻合
上面的内容写了一个小时,我的能量已经耗尽了😩
WebFormsFilterpublic void OnPageHandlerExecuting(PageHandlerExecutingContext context) { //当前页面处理程序的实例 object handlerInstance = context.HandlerInstance; //是否是POST请求 bool flag = context.HttpContext.Request.Method == "POST"; //没用上 HandlerMethodDescriptor handlerMethod = context.HandlerMethod; //如果是POST请求,并且是FineUI的AJAX请求,并且开启了WebForms模式 if (flag && PageContext.IsFineUIAjaxPostBack() && PageManager.Instance.EnableWebForms) { //还原__FSTATE 2️⃣ A(handlerInstance); //找Page_Load并且执行 a(context, handlerInstance); //得到handler方法 1️⃣ MethodInfo methodInfo = A(context, handlerInstance); //如果handler不为null,执行handler方法 if (methodInfo != null) { //解析__EVENTTARGET3️⃣和__EVENTARGUMENT4️⃣ 并执行handler A(context, handlerInstance, methodInfo); } } }
本文作者:没想好
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!