好了,前边我们把核心内容介绍完了,接下来要做的就是拦截用户的请求,并把请求转向沙箱内。

  这里我们准备通过实现一个HttpModule类来完成请求的拦截与转发。新建一个HuberHttpModule类,并继承IHttpModule。下面我们暂时只处理Application_BeginRequest事件。

  先获取request和response对象

    HttpApplication application = sender as HttpApplication;
HttpResponse respond = application.Response;
HttpRequest request = application.Request;

  接下来获取当前请求的url:

string url = request.Url.AbsolutePath.ToString();

  我们做了一个约定,所有模块都放在plugins目录中,即需要判断一下当前url是否以“/plugins/”开头,再判断一下是否为静态文件(通常情况下,我们的action命名是不允许包含“.”的)。

  接下来定义一个UrlPathEntity类,把url转换成UrlPathEntity的实例对象,用来存放url对应的插件名称、插件版本、controller、action。

  

    public class UrlPathEntity
{
/// <summary>
/// //插件名称
/// </summary>
public string pluginname { get; set; }
/// <summary>
/// //插件版本
/// </summary>
public int pluginversion { get; set; }
/// <summary>
/// //控制器名称(包含area)
/// </summary>
public string controller { get; set; }
/// <summary>
/// //action名称
/// </summary>
public string action { get; set; }
}

  下面是url转换方法:  

/// <summary>url解析成对象
/// </summary>
/// <param name="url"></param>
/// <param name="isPlugin">是否为插件</param>
/// <returns></returns>
public static UrlPathEntity getUrlPathEntity(string url, bool isPlugin)
{
UrlPathEntity result = null;
var matchs = url.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
if (isPlugin)
{
//var matchs = PluginRgx.Matches(url);
if (matchs != null && matchs.Length > 0)
{
int _index = 0;
result = new UrlPathEntity();
result.pluginname = matchs[_index++];//插件名称
string _pluginversion = matchs[_index++];//插件版本
int pluginversion = -1;
int.TryParse(_pluginversion, out pluginversion);
result.pluginversion = pluginversion;
string urltemp = "/" + result.pluginname;
for (; _index < matchs.Length - 1;)
{
urltemp += "/" + matchs[_index++];
}
result.action = matchs[_index];//action名称
urltemp += "/" + result.action; CAModel controller = null;//控制器名称(包含area)
UrlRefAction.TryGetValue(urltemp.ToLower(), out controller);
if (controller != null)
{
result.controller = controller.ControllerName.Replace("/", ".");
result.action = controller.ActionName;
}
}
}
else
{
if (matchs != null && matchs.Length > 0)
{
int _index = 0;
result = new UrlPathEntity();
result.controller = string.Empty;//控制器名称(包含area)
for (; _index < matchs.Length - 1;)
{
result.controller += "." + matchs[_index++];
}
result.controller = result.controller.Substring(1);
result.action = matchs[_index];//action名称
}
}
return result;
}

  获取转换后的对象:

var urlEntity = HuberPluginHandle.getUrlPathEntity(url.Substring(8), true);

  根据该对象找到对应的沙箱:

 SandBoxDynamicLoader sandBox = HuberPluginHandle.getSandBox(urlEntity.pluginname, urlEntity.pluginversion);

  我们再把请求中携带的参数打包:

RefRequestEntity paras = new RefRequestEntity();
RequestHandle.FillCorRefEntity(paras, request);

  好了,准备工作做好了,最后一步,沙箱调用:  

 var result = sandBox.InvokeMothod(urlEntity.controller, urlEntity.action, paras);

  这个result就是我们想要的结果了,接下来我们要做的就是把这个result返回了

RequestHandle.ResposeResult(respond, result);

  至此,我们自定义的请求管道就算完成了,这其中为了防止通篇代码带来的反感,就省略了好多辅助业务,希望大家谅解。

本来还想把权限管理什么的些进来,后来想了想,这个系列主要是讲框架的原理,而且权限那块是基于sqlite写的,不具有规模并发能力,代码已经开源出来了,地址:https://github.com/Eric-zsp/Huber.net

这个系列暂时先写到这里吧。

转载请注明出处:http://www.cnblogs.com/eric-z/p/5108862.html 

第五篇 基于.net搭建热插拔式web框架(拦截器---请求管道)的更多相关文章

  1. 第三篇 基于.net搭建热插拔式web框架(重造Controller)

    由于.net MVC 的controller 依赖于HttpContext,而我们在上一篇中的沙箱模式已经把一次http请求转换为反射调用,并且http上下文不支持跨域,所以我们要重造一个contro ...

  2. 第二篇 基于.net搭建热插拔式web框架(沙箱的构建)

    上周五写了一个实现原理篇,在评论中看到有朋友也遇到了我的问题,真的是有种他乡遇知己的感觉,整个系列我一定会坚持写完,并在最后把代码开源到git中.上一篇文章很多人看了以后,都表示不解,觉得不知道我到底 ...

  3. 第四篇 基于.net搭建热插拔式web框架(RazorEngine实现)

    在开头也是先给大家道个歉,由于最近准备婚事导致这篇文章耽误了许久,同时也谢谢老婆大人对我的支持. 回顾上篇文章,我们重造了一个controller,这个controller中用到了视图引擎,我们的视图 ...

  4. 基于.net搭建热插拔式web框架(实现原理)

    第一节:我们为什么需要一个热插拔式的web框架? 模块之间独立开发 假设我们要做一个后台管理系统,其中包括“用户活跃度”.“产品管理”."账单管理"等模块.每个模块中有自己的业务特 ...

  5. net搭建热插拔式web框架

    net搭建热插拔式web框架(重造Controller) 由于.net MVC 的controller 依赖于HttpContext,而我们在上一篇中的沙箱模式已经把一次http请求转换为反射调用,并 ...

  6. net搭建热插拔式web框架(沙箱的构建)

    net搭建热插拔式web框架(沙箱的构建) 上周五写了一个实现原理篇,在评论中看到有朋友也遇到了我的问题,真的是有种他乡遇知己的感觉,整个系列我一定会坚持写完,并在最后把代码开源到git中.上一篇文章 ...

  7. 带你手写基于 Spring 的可插拔式 RPC 框架(一)介绍

    概述 首先这篇文章是要带大家来实现一个框架,听到框架大家可能会觉得非常高大上,其实这和我们平时写业务员代码没什么区别,但是框架是要给别人使用的,所以我们要换位思考,怎么才能让别人用着舒服,怎么样才能让 ...

  8. 转-基于NodeJS的14款Web框架

    基于NodeJS的14款Web框架 2014-10-16 23:28 作者: NodeJSNet 来源: 本站 浏览: 1,399 次阅读 我要评论暂无评论 字号: 大 中 小 摘要: 在几年的时间里 ...

  9. 两个基于C++/Qt的开源WEB框架

    1.tufao 项目地址: https://github.com/vinipsmaker/tufao 主页: http://vinipsmaker.github.io/tufao/ 介绍: Tufão ...

随机推荐

  1. [No00009E]几种常见的命名规则

    变量命名规则 必须遵循的命名规则 1.    变量名首字母必须为字母(a-z A-Z),下划线(_),或者美元符号($)开始php编程中所有变量必须以$开始. 2.    变量名只能是字母(a-z A ...

  2. 解读ASP.NET 5 & MVC6系列(11):Routing路由

    新版Routing功能介绍 在ASP.NET 5和MVC6中,Routing功能被全部重写了,虽然用法有些类似,但和之前的Routing原理完全不太一样了,该Routing框架不仅可以支持MVC和We ...

  3. [LeetCode] Combine Two Tables 联合两表

    Table: Person +-------------+---------+ | Column Name | Type | +-------------+---------+ | PersonId ...

  4. 10大H5前端框架

    作为一名做为在前端死缠烂打6年并且懒到不行的攻城士,这几年我还是阅过很多同门从知名到很知名的各种前端框架,本来想拿15-20个框架来分享一下,但在跟几个前辈讨教写文章的技巧时果断被无情的打击了,所以这 ...

  5. ant windows环境配置

    详见如下链接,小蚂蚁builder.xml--apache-ant的配置 http://blog.csdn.net/gaohuanjie/article/details/40142687

  6. 【WPF】释放图像资源, [删除时报另一进程占用]

    源:zhantianyou CODE private BitmapImage ReturnBitmap(string destFile) { // Read byte[] from png file ...

  7. php curl获取的数据不直接输出

    curl获取页面内容,不直接输出到页面 必需设置curl的CURLOPT_RETURNTRANSFER选项为1或true curl_setopt($ch, CURLOPT_RETURNTRANSFER ...

  8. 两种遍历list

    li=[[1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5]]s=0for i in range(0,5): for j in ran ...

  9. css学习笔记(1)

    为什么要重新学css,理由有很多,css这个小婊砸,接触至今已有三年,但真的说熟练恐怕不见得.特此,为了我的目标,开始重新整理css的知识,我希望,每一篇笔记都能有个例子,从而来巩固我的知识. 在学习 ...

  10. 【BZOJ-3998】弦论 后缀自动机

    3998: [TJOI2015]弦论 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2018  Solved: 662[Submit][Status] ...