最精简的自定义.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)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 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的设计模式综述