• 第五篇 基于.net搭建热插拔式web框架(拦截器---请求管道)


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

      这里我们准备通过实现一个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 
  • 相关阅读:
    C# treeView添加节点 删除节点
    xml 基础
    第一章魔兽窗口
    混合开发的框架的初步见解
    node.js的初步见解
    AngularJs的理解
    jquery属性,遍历,HTML操作
    jquery中动画效果的函数
    jquery的选择器
    js操作DOM对象及怎么获取浏览器宽高
  • 原文地址:https://www.cnblogs.com/eric-z/p/5108862.html
Copyright © 2020-2023  润新知