重写IHttpHandler,实现前后端分离
再说重写IHttpHandler,实现前后端分离
aspx页面第一次加载时,HttpHandler 里面是如何编译指定页面的呢?Framework提供了编译页面的API如下:
BuildManager.CreateInstanceFromVirtualPath(url, typeof(System.Web.UI.Page));根据虚拟路径生成实例。
但是url页面此时必需继承System.Web.UI.Page,就是我们常见的ASPX页面。但是这样编译时会调用aspx视图引擎来解析aspx和对应的CodeBehind类。
对于前台纯粹用JSON渲染的JS插件,解析编译ASPX页面似乎是多余的,aspx的生命周期也是复杂和没什么卵用的,那问题来了,能不能只编译类文件(当然要继承IHttpHandler),而aspx页面用html替换呢?
如下图的结构,(如何一键建立这样的文件结构下次再说,MVC中View和Controller分的太开了,不太习惯,中小型项目还是这样觉的更好。)
目标:html上发送ajax请求到.cs上,并返回数据到.html

Framework提供一个方法:
var ass = BuildManager.GetCompiledAssembly(url);根据虚拟路径得到程序集。第一次加载需要编译慢一点,之后会很快。
url可以是这样:/Portal/ListPageTmp.cs,即根据class文件路径生成Assembly,
当然此时浏览器url是/Portal/ListPageTmp.html
我们可以在前台ajax请求时就把路径由/Portal/ListPageTmp.html转换成/Portal/ListPageTmp.cs,再发送ajax,也可以在后台GetHandler方法里面转换。
我是在前台转换的如下:(把$.ajax封装一下,确保所有AJAX都调用此方法以便转换url)
$.ajax({
type: 'post',
url: ‘/Portal/ListPageTmp.cs’,
async: async,
data: data,
success: function (data) { rtn = data; },
error: function (data) { rtn["result"] = "fail"; alert("操作失败") },
dataType: 'json'
});
要想以这样ajax请求(/Portal/ListPageTmp.cs)让IIS接收到 那必然要改web.Config:不解释
<system.webServer>
<handlers>
<add name="ddd" verb="*" path="*.cs" type="App.PageBase.CSHttpHandler" />
</handlers>
</system.webServer>
以下是IHttpHandlerFactory完整代码:

1 public class CSHttpHandler : IHttpHandlerFactory
2 {
3 public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
4 {
5
6 try
7 {
8 var ass = BuildManager.GetCompiledAssembly(url);//重要的一个方法,也见过其它的跟据url生成实例的方法,但是如果不同命名空间有同名类就不好办了。
9 // var d = BuildManager.CreateInstanceFromVirtualPath(url, typeof(System.Web.UI.Page));
10
11 TypeInfo pageType = ass.DefinedTypes.Where(p => p.IsClass == true && p.BaseType.BaseType == typeof(BasePage)).FirstOrDefault();
12 BasePage basepage = Activator.CreateInstance(pageType) as BasePage;
13 return (IHttpHandler)basepage;
14 }
15 catch (Exception ex)
16 {
17 throw ex;
18 }
19
20 }
21
22 public void ReleaseHandler(IHttpHandler handler)
23 {
24
25
26 }
27
28 }

BasePage类,和System.Web.UI.Page类功能相当。

1 public class BasePage : IHttpHandler
2 {
3
4 private bool _IsAjaxRequest;
7 private string _Action;
8 private ActionResult _ActionResult;
9 AppCache cache = new AppCache();
10 public BasePage()
11 {
12 this.IsCheckLogin = true;
13
14 this.IsCheckAuth = true;
15
16 _ActionResult = new ActionResult();
17
18
19
20 }
21
22 public bool IsReusable { get; set; }
23 protected HttpRequest Request
24 {
25 get;
26 set;
27 }
28 protected HttpResponse Response
29 {
30 get;
31 set;
32 }
33
34 public virtual void ProcessRequest(HttpContext context)
35 {
36 this.Request = context.Request;
37 this.Response = context.Response;
38 this.OnInit();
39
40 }
41 protected string Action
42 {
43 get
44 {
45 return _Action;
46 }
47
48
49 }
//判断是否AJAX请求,这种模式,到这里的请求都是AJAX请求,因为HTML加载时不用触发请求到后端的。
50 protected bool IsAjaxRequest
51 {
52 get
53 {
54 return _IsAjaxRequest;
55 }
56
57
58 }
59 protected virtual void OnInit()
60 {
61 _IsAjaxRequest = this.Request.Headers["X-Requested-With"] == "XMLHttpRequest" ? true : false;
62 _Action = Request.QueryString["Action"] == null ? "" : Request.QueryString["Action"].ToString();
63 form = new FormData(Request.Form);
//根据URL上的Action参数找到继承此类上的方法,并反射调用。
MethodInfo method = this.GetType().GetMethod(Action);
if (method == null)
{
throw new Exception("找不到【" + method.Name + "】方法.");
}
else
{
try
{
//绑定参数并调用,当然调用前也可以也可以做ActionFilter检查
InvokMethod(this, method);
}
catch (Exception ex)
{
actionResut.hasError = true;
actionResut.message = ex.InnerException.Message;
}
}
//返回json数据
ReturnData(actionResut);
64 }
//绑定Action方法的参数。
65 protected object InvokMethod(object ins, MethodInfo method)
66 {
67
68
69 var methodParam = method.GetParameters();
70 object[] param = new object[methodParam.Length];
71 for (int i = 0; i < methodParam.Length; i++)
72 {
73 string name = methodParam[i].Name;
74 Type paramType = methodParam[i].ParameterType;
75 if (paramType.IsGenericType) paramType = paramType.GetGenericArguments()[0];
76 string ArgValue = Request.QueryString[name];
77 string FormValue = Request.Form[name];
78 string value = string.IsNullOrEmpty(ArgValue) ? FormValue : ArgValue;
79 if (!string.IsNullOrEmpty(value))
80 {
81 if (paramType.IsValueType)
82 {
83 param[i] = Convert.ChangeType(value, paramType);
84 }
85 else if (paramType == typeof(string))
86 {
87 param[i] = value;
88 }
89 else
90 {
91 param[i] = JsonHelper.Json2Object(value.ToString(), paramType);
92 }
93 }
94
95 else
96 {
97 param[i] = null;
98 }
99 }
100 return method.Invoke(ins, param);
101
102 }
103 }

ListPageTmp.html对应的类文件是这样的:
如果有ListPageTmp.html?Action=Test&Id=1&name=zhangsan的ajax请求,会根据名称找到ListPageTmp.cs,实例化后将url参数绑定到Test方法参数上执行,返回JSON.

1 public partial class ListPageTmp :BasePage
2 {
3
[Auth(Role="Admin")]//反射调用前也可检查是否有attribute并做 拦截 ,类似MVC的ActionFilter.
4 public void Test(int Id,string name)
5 {
6
7 actionResut.Add("Name",name);
actionResut.Add("Id",Id);
8
9 }
10
11
12
13 }

这样前后端就分开了。html加载完成后,根据不同需要发送ajax从服务端取json数据绑定的前台。
也实现了MVC里面的一些功能,如ActionFilter,Action参数绑定,ActionResult和MVC的不太一样。没有很复杂的ActionResult,只是封装json.
MVC是通过URL 路由 找到 Control和Action,由Action定向到View,
今天说的这个方案,是通过View找到Control和Action 执行后返回JSON给View.
唉,不知道说明白了没有。。。。
重写IHttpHandler,实现前后端分离的更多相关文章
- 再说重写IHttpHandler,实现前后端分离
aspx页面第一次加载时,HttpHandler 里面是如何编译指定页面的呢?Framework提供了编译页面的API如下: BuildManager.CreateInstanceFromVirtua ...
- [转] 前后端分离开发模式的 mock 平台预研
引入 mock(模拟): 是在项目测试中,对项目外部或不容易获取的对象/接口,用一个虚拟的对象/接口来模拟,以便测试. 背景 前后端分离 前后端仅仅通过异步接口(AJAX/JSONP)来编程 前后端都 ...
- 【开源.NET】 分享一个前后端分离的轻量级内容管理框架
开发框架要考虑的面太多了:安全.稳定.性能.效率.扩展.整洁,还要经得起实践的考验,从零开发一个可用的框架,是很耗时费神的工作.网上很多开源的框架,为何还要自己开发?我是基于以下两点: 没找到合适的: ...
- [原创]基于VueJs的前后端分离框架搭建之完全攻略
首先请原谅本文标题取的有点大,但并非为了哗众取宠.本文取这个标题主要有3个原因,这也是写作本文的初衷: (1)目前国内几乎搜索不到全面讲解如何搭建前后端分离框架的文章,讲前后端分离框架思想的就更少了, ...
- 从壹开始前后端分离[.NetCore] 37 ║JWT完美实现权限与接口的动态分配
缘起 本文已经有了对应的管理后台,地址:https://github.com/anjoy8/Blog.Admin 哈喽大家好呀!又过去一周啦,这些天小伙伴们有没有学习呀,已经有一周没有更新文章了,不过 ...
- 一个Java程序猿眼中的前后端分离以及Vue.js入门
松哥的书里边,其实有涉及到 Vue,但是并没有详细说过,原因很简单,Vue 的资料都是中文的,把 Vue.js 官网的资料从头到尾浏览一遍该懂的基本就懂了,个人感觉这个是最好的 Vue.js 学习资料 ...
- 从壹开始前后端分离 [.netCore 填坑 ] 三十三║ ⅖ 种方法实现完美跨域
缘起 哈喽大家周四好,趁着大家在团建的时候花一个下午学点儿东西,也是督促大家学习哟,希望大家看到老张的文章,可以有一丢丢的学习动力.不过话说过来,该吃的团建还是要去的,不能学我呀 [ /(ㄒoㄒ)/~ ...
- 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之七 || API项目整体搭建 6.2 轻量级ORM
更新 1.在使用的时候,特别是更新数据的时候,如果不知道哪里有问题,可以查看数据库 和 实体类 的字段,是否大小写一致,比如 name 和 Name 2.在使用Sqlsugar 的 CodeFirst ...
- 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十 || AOP面向切面编程浅解析:简单日志记录 + 服务切面缓存
代码已上传Github+Gitee,文末有地址 上回<从壹开始前后端分离[ .NET Core2.0 Api + Vue 2.0 + AOP + 分布式]框架之九 || 依赖注入IoC学习 + ...
随机推荐
- HDU4144:Bacon's Cipher
Problem Description Bacon's cipher or the Baconian cipher is a method of steganography (a method of ...
- 在JAVA中使用LUA脚本记,javaj调用lua脚本的函数(转)
最近在做一些奇怪的东西,需要Java应用能够接受用户提交的脚本并执行,网络部分我选择了NanoHTTPD提供基本的HTTP服务器支持,并在Java能承载的许多脚本语言中选择了很久,比如Rhino,Jy ...
- 做web项目时对代码修改后浏览器端不生效的应对方法(持续更新)
做web项目时,经常会遇到修改了代码,但浏览器端没有生效,原因是多种多样的,我会根据我遇到的情况逐步更新解决办法 1.运行的时候采用debug模式,一般情况下使用项目部署按钮右边那个按钮下的tomca ...
- redis入门(转)
Redis介绍 Redis是一种高级key-value数据库.它跟memcached类似,不过数据可以持久化,而且支持的数据类型很丰富.有字符串,链表.哈希.集合和有序集合5种.支持在服务器端计算集合 ...
- Centos memcached的php拓展 管理界面
确定已安装apache 一.安装php5 1.安装libxml2 tar zxvf libxml2-.tar.gz cd libxml2- ./configure --prefix=/usr/loca ...
- 安装gcc 3.4
安装 gcc 3.4 f**k,不是为了编译0.11内核.我才懒得鸟3.4的版本号 源代码编译被我实践--"不归路",各种报错,我起码不止是了4个版本号的gcc,各种不兼容.各 ...
- 乐在其中设计模式(C#) - 装饰模式(Decorator Pattern)
原文:乐在其中设计模式(C#) - 装饰模式(Decorator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 装饰模式(Decorator Pattern) 作者:weba ...
- cnBlog 的windows live writer 客户端配置
重装系统后总是忘,备个档 CNBLOG 博客名 cnblog 日志帐户 http://www.cnblogs.com/liulaocai2/ 用户:359444066 密码:同QQ密码,比QQ少一位 ...
- java编程规范之java注释规范
代码要是没有注释,对读者来说就是一堆乱七八糟的字母,为了提高代码的可读性和可维护性,必须对代码进行必要的注释,这里小编整理了一下java注释规范. (一)技巧 1:注释当前行快捷方式:ctrl+/ 2 ...
- 一个不错的 png压缩工具 pngquant 使用介绍 批量压缩png
1.Png 简介. 我们知道Png 有4个通道,RGBA, 多了一个表示透明的.png 有 png 32, 24, 8 等. 大致我理解的是表示颜色的多少. 数字越小,文件就越小.常见的压缩方式是导入 ...