随笔 - 35  文章 - 0  评论 - 121  阅读 - 56623

最精简的自定义.net 开发框架

一、 通过自定义的HttpModule和HttpHandler,重写url,自定义路由规则,实现 Web API功能。 简单说

       就是  请求路径 例如 service/method, 那么就指向当前应用app下某个services的某个方法method。

首先,实现IHttpModule,对于请求路径 符合自定义规则的,交给自定义的HttpHandler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public class UrlRoutingModule : IHttpModule
    {
        //其他成员
        public RouteCollection RouteCollection { get; set; }
        public void Init(HttpApplication context)
        {
            context.PostResolveRequestCache += new EventHandler(this.OnApplicationPostResolveRequestCache);
      
        }
         
        private void OnApplicationPostResolveRequestCache(object sender, EventArgs e)
       {        
           HttpContext context = ((HttpApplication)sender).Context;
           string path = context.Request.AppRelativeCurrentExecutionFilePath;
           
            //为了解决iis6 中framework4.0 与 framework2.0共存的问题
            if (path.EndsWith("/eurl.axd"))
           {
               path = path.Substring(0, path.Length - 9);
           }
 
           string[] pathArray = path.Split('/');
           string fileName = pathArray[pathArray.Length - 1];
          
           if (fileName.IndexOf(".") > 0)
           {
               context.RemapHandler(HttpContext.Current.Handler);
           }
           else
           {
               PageRouteHandler handler = new PageRouteHandler();
               context.RemapHandler(handler);
           }
       }
 
        #region IHttpModule 成员
 
        public void Dispose()
        {
           
            
 
        }
 
        #endregion
    }

  

自定义的httphandler 实现 IHttpHandler接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
  public class PageRouteHandler : IHttpHandler
    {
        public bool IsReusable
        {
            get { return true; }
 
        }
 
        public void ProcessRequest(HttpContext context)
        {
            string result = string.Empty;
            string path = context.Request.AppRelativeCurrentExecutionFilePath;
            string[] pathArray = path.Split('/');
            Func<HttpContext, string> handler = null;
 
            string serviceName = string.Empty;
            string methodName = string.Empty;
            if (pathArray.Length >= 3)
            {
                serviceName = pathArray[1];
                methodName = pathArray[2];
            }
 
            if (!string.IsNullOrEmpty(serviceName) && !string.IsNullOrEmpty(methodName))
            {
                handler = GetWebMethod(serviceName + "." + methodName);
                if (handler != null)
                {
                    result = handler(context);
                }
            }
            if (handler == null)
            {
                result = "{\"result\":\"not exist handler service\"}";
 
            }
 
            if (context.Request.AcceptTypes != null && context.Request.AcceptTypes.Contains("application/json"))
            {
                context.Response.ContentType = "application/json";
            }
 
            string callback = context.Request["jsoncallback"];
            if (!string.IsNullOrEmpty(callback))
            {
                result = callback + "(" + result + ")";
                context.Response.AddHeader("Access-Control-Allow-Origin", "*");
            }
 
            context.Response.Write(result);
 
        }
}

  

自定义的 pageroutehandler的作用,就是处理合法请求时,通过委托方式调用请求的方法,并把结果返回。 获取委托时使用了缓存,getwebmethod 代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public static Dictionary<string, Func<HttpContext, string>> WebMethods
     {
         get
         {
             Dictionary<string, Func<HttpContext, string>> _webMethods = HttpRuntime.Cache["WebMethods"] as Dictionary<string, Func<HttpContext, string>>;
             if (_webMethods == null)
             {
                 _webMethods = new Dictionary<string, Func<HttpContext, string>>();
             }
             return _webMethods;
         }
     }
 
     public static Func<HttpContext, string> GetWebMethod(string classMethodName)
     {
         if (string.IsNullOrEmpty(classMethodName))
         {
             return null;
         }
         string[] arrClassMethod = classMethodName.Split('.');
         if (arrClassMethod.Length != 2)
         {
             return null;
         }
 
         Func<HttpContext, string> handler = null;
         if (!WebMethods.ContainsKey(classMethodName))
         {
 
             string binPath = AppDomain.CurrentDomain.RelativeSearchPath;
             foreach (string dll in Directory.GetFiles(binPath))
             {
                 FileInfo fi = new FileInfo(dll);
                 if (fi.Extension.Equals(".dll", StringComparison.CurrentCultureIgnoreCase) && !fi.Name.StartsWith("system.") && !fi.Name.StartsWith("microsoft."))
                 {
                     Assembly assembly = Assembly.LoadFile(dll);
                     string typeName = assembly.GetName().Name + "." + arrClassMethod[0];
                     Type type = assembly.GetType(typeName, false, true);
                     if (type != null)
                     {
                         handler = (Func<HttpContext, string>)Delegate.CreateDelegate(typeof(Func<HttpContext, string>), type.GetMethod(arrClassMethod[1], BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Static, null, new Type[1] { typeof(HttpContext) }, null));
                         WebMethods.Add(classMethodName, handler);
                         break;
                     }
                 }
             }
           
         }
         else
         {
             handler = WebMethods[classMethodName];
         }
         return handler;
     }

  

二  使用规则。首先在web config 的<httpModules>加上<add name="RouteModule" type="LinWebAPI.UrlRoutingModule, LinWebAPI"/>(这里type就是 你自己定义的httpmodule的类的全名了)。

    只要你把你的后台类暴露出来给前台调用,定义方法符合    public static string  method(HttpContext context)   这个规则即可。

   假设 你有个模块的类 TestServices  下有个 方法  public  static  string TestMethod(HttpContext context), 那么前端页面 通过 ajax请求路径为  Testservices/testmethod,

  至于请求的参数,你可以通过?a=x&b=y这种方式加到请求路径后面,也可以放通过post方式提交  例如  jquery的 $.ajax(url,{a:x,b:y}....。

  而对于 方法 TestMethod(HttpContext context),要获取请求的参数,直接从 string a = context.Request["a"]  即可。

  ***  

对于iis6,要支持这种不带扩展名的请求路径,需要

1. 打开 IIS Microsoft 管理控制台 (MMC),右键单击本地计算机名称,然后单击“属性”。
2. 单击“MIME 类型”。
3. 单击“新建”。
4. 在“扩展名”框中,键入星号 (*)。
5. 在“MIME 类型”框中,键入 application/octet-stream。

对于iis7,要支持这种不带扩展名的请求路径,需要

1 网站托管模式为 经典模式
2 处理程序映射--》添加脚本映射--》配置(请求路径:* ;可执行文件:C:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll)

posted on   lindping  阅读(398)  评论(1编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示