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

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

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

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接口

  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 代码如下

   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)

最精简的自定义.net 开发框架的更多相关文章

  1. HTC one/M7电信802d 毒蛇ViperOne2.1.0/高级毒蛇工具/完美root,精简/更多自定义,稳定,流畅ROM

    ROM版本 HTC One/M7 802d ROM作者 雪狼团队·大盛 http://weibo.com/DaShengdd Android版本 Android 4.2.2 创建日期 2013.09. ...

  2. 精简版自定义 jquery

    function $(id) { var el = 'string' == typeof id ? document.getElementById(id) : id; el.on = function ...

  3. 可靠通信的保障 —— 使用ACK机制发送自定义信息——ESFramework 通信框架4.0 快速上手(12)

    使用ESPlus.Application.CustomizeInfo.Passive.ICustomizeInfoOutter接口的Send方法,我们已经可以给服务端或其它在线客户端发送自定义信息了, ...

  4. 一个自定义python分布式专用爬虫框架。支持断点爬取和确保消息100%不丢失,哪怕是在爬取进行中随意关停和随意对电脑断电。

    0.此框架只能用于爬虫,由框架来调度url请求,必须按照此方式开发,没有做到类似celery的通用分布式功能,也不方便测试.可以使用另外一个,基于函数式编程的,调度一切函数的分布式框架,做到了兼容任何 ...

  5. RESTful登录设计(基于Spring及Redis的Token鉴权)

    转载自:http://www.scienjus.com/restful-token-authorization/ http://m.blog.csdn.net/article/details?id=4 ...

  6. App后台开发运维和架构实践学习总结(1)——App后台核心技术之用户验证方案

    对于初学者来说,对Token和Session的使用难免会限于困境,开发过程中知道有这个东西,但却不知道为什么要用他?更不知道其原理,今天我就带大家一起分析分析这东西. 一.使用Token进行身份鉴权 ...

  7. HikariCP 连接最快的连接池

    三点原因 1.字节码精简 2.自定义 FastList 代替ArrayList ;避免每次get()调用都要进行range check,避免调用remove()时的从头到尾的扫描: 3.优化代码和拦截 ...

  8. nodejs的精简型和全栈型开发框架介绍

    总体来说你可以将Node.js开发框架归结为两类: - 精简型框架 - 全栈型框架 下面我们就对这两种框架进行探讨. 精简型框架 精简型框架提供的是最基本的功能和APIs,这类框架本身就是被设计成用来 ...

  9. 干货——基于Nop的精简版开发框架(附源码)

    .NET的开发人员应该都知道这个大名鼎鼎的高质量b2c开源项目-nopCommerce,基于EntityFramework和MVC开发,拥有透明且结构良好的解决方案,同时结合了开源和商业软件的最佳特性 ...

随机推荐

  1. 最新apache多域名多站点配置

    httpd.conf===> Listen Listen ServerName 用IP地址作为servername LoadModule rewrite_module modules/mod_r ...

  2. Docker容器里的进程为什么要前台运行?相同的问题:docker运行apache为什么带FOREGROUND参数?docker运行nginx为什么带`daemon off`参数?

    <第一本Docker书>里面,讲到Docker容器启动web服务时,都指定了前台运行的参数. 例如apache: ENTRYPOINT [ "/usr/sbin/apache2& ...

  3. Spring 集成Junit单元测试

    1.在pom增加junit和spring-test <dependency> <groupId>junit</groupId> <artifactId> ...

  4. python3.7安装

    在Ubuntu系统带有原Python环境2.7,3.5,使用pyenv可以将其设置成最新的3.7.1,使用安装步骤如下:(防止丢失所以做了复制,复制来源:https://www.cnblogs.com ...

  5. 基于MVC4+EasyUI的Web开发框架形成之旅(7)--权限控制

    我在上一篇随笔<基于MVC4+EasyUI的Web开发框架形成之旅--框架总体界面介绍>中大概介绍了基于MVC的Web开发框架的权限控制总体思路.其中的权限控制就是分为“用户登录身份验证” ...

  6. CentOS6.4 添加nginx系统服务

    简介: Nginx安装完成后默认不会注册为系统服务,所以需要手工添加系统服务脚本.在/etc/init.d目录下新建nginx文件,并更改权限其即可. 1.新建nginx文件 1.1.新建文件:vi ...

  7. SPI 核软件调试记录

    SPI 核软件调试记录 1.首先说说int SpiFlashWaitForFlashReady(void)这一函数,基本上其它函数在执行的时候,都会事先执行一次此函数.    因为此函数的作用主要是用 ...

  8. Python实战(6)单线程和多线程导入mysql数据对比测试

    单线程脚本 导入文件的行数 # wc -l /data/logs/testlog/20120219/testlog1/* 1510503 total # -*- coding: utf-8 -*- # ...

  9. Delphi:窗体的扩展样式GWL_EXSTYLE用于SetWindowLong

    SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_TRANSPARENT or WS_EX_ ...

  10. 一个简单的PHP短信群发

    function bulksms(){ ignore_user_abort();//关掉浏览器,PHP脚本也可以继续执行. set_time_limit(0);// 通过set_time_limit( ...