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完整代码:

  public class CSHttpHandler : IHttpHandlerFactory
{
public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
{ try
{
var ass = BuildManager.GetCompiledAssembly(url);//重要的一个方法,也见过其它的跟据url生成实例的方法,但是如果不同命名空间有同名类就不好办了。
// var d = BuildManager.CreateInstanceFromVirtualPath(url, typeof(System.Web.UI.Page)); TypeInfo pageType = ass.DefinedTypes.Where(p => p.IsClass == true && p.BaseType.BaseType == typeof(BasePage)).FirstOrDefault();
BasePage basepage = Activator.CreateInstance(pageType) as BasePage;
return (IHttpHandler)basepage;
}
catch (Exception ex)
{
throw ex;
} } public void ReleaseHandler(IHttpHandler handler)
{ } }
BasePage类,和System.Web.UI.Page类功能相当。
     public class BasePage : IHttpHandler
{ private bool _IsAjaxRequest;
private string _Action;
private ActionResult _ActionResult;
AppCache cache = new AppCache();
public BasePage()
{
this.IsCheckLogin = true; this.IsCheckAuth = true; _ActionResult = new ActionResult(); } public bool IsReusable { get; set; }
protected HttpRequest Request
{
get;
set;
}
protected HttpResponse Response
{
get;
set;
} public virtual void ProcessRequest(HttpContext context)
{
this.Request = context.Request;
this.Response = context.Response;
this.OnInit(); }
protected string Action
{
get
{
return _Action;
} }
//判断是否AJAX请求,这种模式,到这里的请求都是AJAX请求,因为HTML加载时不用触发请求到后端的。
protected bool IsAjaxRequest
{
get
{
return _IsAjaxRequest;
} }
protected virtual void OnInit()
{
_IsAjaxRequest = this.Request.Headers["X-Requested-With"] == "XMLHttpRequest" ? true : false;
_Action = Request.QueryString["Action"] == null ? "" : Request.QueryString["Action"].ToString();
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);

         }
//绑定Action方法的参数。
protected object InvokMethod(object ins, MethodInfo method)
{ var methodParam = method.GetParameters();
object[] param = new object[methodParam.Length];
for (int i = ; i < methodParam.Length; i++)
{
string name = methodParam[i].Name;
Type paramType = methodParam[i].ParameterType;
if (paramType.IsGenericType) paramType = paramType.GetGenericArguments()[];
string ArgValue = Request.QueryString[name];
string FormValue = Request.Form[name];
string value = string.IsNullOrEmpty(ArgValue) ? FormValue : ArgValue;
if (!string.IsNullOrEmpty(value))
{
if (paramType.IsValueType)
{
param[i] = Convert.ChangeType(value, paramType);
}
else if (paramType == typeof(string))
{
param[i] = value;
}
else
{
param[i] = JsonHelper.Json2Object(value.ToString(), paramType);
}
} else
{
param[i] = null;
}
}
return method.Invoke(ins, param); }
}
ListPageTmp.html对应的类文件是这样的:
如果有ListPageTmp.html?Action=Test&Id=1&name=zhangsan的ajax请求,会根据名称找到ListPageTmp.cs,实例化后将url参数绑定到Test方法参数上执行,返回JSON.
 
     public partial class ListPageTmp :BasePage
{

[Auth(Role="Admin")]//反射调用前也可检查是否有attribute并做 拦截 ,类似MVC的ActionFilter.
public void Test(int Id,string name)
{ actionResut.Add("Name",name);
               actionResut.Add("Id",Id);
         }

     }

这样前后端就分开了。html加载完成后,根据不同需要发送ajax从服务端取json数据绑定的前台。

也实现了MVC里面的一些功能,如ActionFilter,Action参数绑定,ActionResult和MVC的不太一样。没有很复杂的ActionResult,只是封装json.

MVC是通过URL 路由 找到 Control和Action,由Action定向到View,

今天说的这个方案,是通过View找到Control和Action 执行后返回JSON给View.

唉,不知道说明白了没有。。。。

再说重写IHttpHandler,实现前后端分离的更多相关文章

  1. 重写IHttpHandler,实现前后端分离

    再说重写IHttpHandler,实现前后端分离   aspx页面第一次加载时,HttpHandler 里面是如何编译指定页面的呢?Framework提供了编译页面的API如下: BuildManag ...

  2. [转] 前后端分离开发模式的 mock 平台预研

    引入 mock(模拟): 是在项目测试中,对项目外部或不容易获取的对象/接口,用一个虚拟的对象/接口来模拟,以便测试. 背景 前后端分离 前后端仅仅通过异步接口(AJAX/JSONP)来编程 前后端都 ...

  3. 【开源.NET】 分享一个前后端分离的轻量级内容管理框架

    开发框架要考虑的面太多了:安全.稳定.性能.效率.扩展.整洁,还要经得起实践的考验,从零开发一个可用的框架,是很耗时费神的工作.网上很多开源的框架,为何还要自己开发?我是基于以下两点: 没找到合适的: ...

  4. [原创]基于VueJs的前后端分离框架搭建之完全攻略

    首先请原谅本文标题取的有点大,但并非为了哗众取宠.本文取这个标题主要有3个原因,这也是写作本文的初衷: (1)目前国内几乎搜索不到全面讲解如何搭建前后端分离框架的文章,讲前后端分离框架思想的就更少了, ...

  5. 从壹开始前后端分离[.NetCore] 37 ║JWT完美实现权限与接口的动态分配

    缘起 本文已经有了对应的管理后台,地址:https://github.com/anjoy8/Blog.Admin 哈喽大家好呀!又过去一周啦,这些天小伙伴们有没有学习呀,已经有一周没有更新文章了,不过 ...

  6. 一个Java程序猿眼中的前后端分离以及Vue.js入门

    松哥的书里边,其实有涉及到 Vue,但是并没有详细说过,原因很简单,Vue 的资料都是中文的,把 Vue.js 官网的资料从头到尾浏览一遍该懂的基本就懂了,个人感觉这个是最好的 Vue.js 学习资料 ...

  7. 从壹开始前后端分离 [.netCore 填坑 ] 三十三║ ⅖ 种方法实现完美跨域

    缘起 哈喽大家周四好,趁着大家在团建的时候花一个下午学点儿东西,也是督促大家学习哟,希望大家看到老张的文章,可以有一丢丢的学习动力.不过话说过来,该吃的团建还是要去的,不能学我呀 [ /(ㄒoㄒ)/~ ...

  8. 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之七 || API项目整体搭建 6.2 轻量级ORM

    更新 1.在使用的时候,特别是更新数据的时候,如果不知道哪里有问题,可以查看数据库 和 实体类 的字段,是否大小写一致,比如 name 和 Name 2.在使用Sqlsugar 的 CodeFirst ...

  9. 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十 || AOP面向切面编程浅解析:简单日志记录 + 服务切面缓存

    代码已上传Github+Gitee,文末有地址 上回<从壹开始前后端分离[ .NET Core2.0 Api + Vue 2.0 + AOP + 分布式]框架之九 || 依赖注入IoC学习 + ...

随机推荐

  1. js生成随机数的方法小结

    js生成随机数主要用到了内置的Math对象的random()方法.用法如:Math.random().它返回的是一个 0 ~ 1 之间的随机数.有了这么一个方法,那生成任意随机数就好理解了.比如实际中 ...

  2. Edwin windows下基本命令:

    Ctrl-Alt-z: 对区域内所有代码求值. Ctrl-x Ctrl-e: 对光标左边或上一个表达式求值. Ctrl-c Ctrl-x: 中断当前求值. Ctrl-a: 移动到行首. Ctrl-e: ...

  3. Catel帮助手册-Catel.Core:(1)参数检查

      我们检查方法是否正确,一般是返回对错,或者是是否抛出一个异常,大部分人不检查异常的正确性,那么这种错误在很深的堆栈中,很难查看. Catel与一般的检查方法不同,一般是使用   public vo ...

  4. .NET定时发送邮件

    添加一个全局应用程序类Global.asax 代码会在访问网站时运行 Global.asax代码: void Application_Start(object sender, EventArgs e) ...

  5. asp.net 发送邮件代码 System.Net.Mail

    前台页面 SendEmail.aspx 代码 using System.Net.Mail;using System.Net; <h2> 发送电子邮件演示 </h2> <t ...

  6. myeclipse笔记(3):导入的项目切换jdk版本

    有时候,从外面导入的javaweb项目会访问不了,这个时候改变jdk版本就是其中解决的方法之一. 右键点击项目 --> bulid path --> configure​ ​​​ 选择需要 ...

  7. dede留言板BUG解决

    dede留言板刷新后空白BUG解决 DEDE留言板验证码留空或者不正确返回空白页面的解决方法 解决方法如下进入文件/plus/guestbook.php 找到代码ShowMsg("验证码不正 ...

  8. Hadoop学习历程(三、第一个程序)

    根据之前的操作,我们已经可以正常的启动Hadoop了,关于真正的集群我会在之后进行说明.现在我们来看一下第一个程序吧 1. 在eclipse上建立一个java项目 2. 将 /usr/hadoop/s ...

  9. Android性能优化学习

    工作以来,越来越觉得性能优化的重要性,从技术角度,它甚至成了决定一个app成败的最关键因素.因此,特地花时间去学习专研性能优化的方法. 学习性能优化最便捷的方式便是研读别人有关性能优化的博客,然而网上 ...

  10. 深入理解7816(5)-----关于文件DF/EF/MF/FID/AID/SFI

    刚开始接触CPU卡的时候,对于各种文件.应用的定义容易模糊不清,通常不能准确地界定什么是文件?什么是应用?DF和EF的区别真的就像计算机里的目录和文档那样吗?FID.AID.SFI这些概念都在什么时候 ...