web api中的RouteHandler
ASP.NET MVC4中引入的Web API可以说是进行REST软件开发的利器(个人意见),但是最近在web form中混入web api时,发现一个问题:由于以前的web form项目中,使用到了session(包括那些复杂的底层逻辑),所以为了最小改动,必须保证web api能支持session。而web api默认情况下,是不支持session的。
问题重现
重现这个不支持session的问题,其实很简单。只需要新建一个web api项目,然后修改ValuesController的Get方法为:
public string Get()
{
return HttpContext.Current.Session == null ? "Session is null" : string.Format("SessionID is '{0}'", HttpContext.Current.Session.SessionID);
}
在运行后,发现页面输出为:"Session is null"。
解决方案
经过一番努力,发现Route中有一个IRouteHandler类型的属性RouteHandler,而默认情况下,这个RouteHandler是System.Web.Http.WebHost.HttpControllerRouteHandler,而HttpControllerRouteHandler中的GetHttpHandler会返回一个IHttpHandler的对象,来对web api的请求进行预处理。对于IHttpHandler其实大家应该不陌生,这个正是asp.net web form中,经常使用到的iis管道处理的一个环节。那么为了让IHttpHandler支持session,我们知道只需要实现一个标记接口IRequiresSessionState。而默认的System.Web.Http.WebHost.HttpControllerHandler只实现了IHttpHandler并没有实现IRequiresSessionState。所以问题就变成了如何让IRouteHandler的GetHttpHandler方法返回一个既实现了IHttpHandler,又实现了IRequiresSessionState对象。所以有了下面的类:
public class WebApiSessionControllerHandler : HttpControllerHandler, IRequiresSessionState
{
public WebApiSessionControllerHandler(RouteData routeData) : base(routeData) { }
}
为了使用WebApiSessionControllerHandler,还需要实现一个IRouteHandler自定义类:
public class WebApiSessionRouteHandler : HttpControllerRouteHandler
{
protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return new WebApiSessionControllerHandler(requestContext.RouteData);
}
}
接下来,就是要让WebApiSessionRouteHandler真正起作用的时候了,只需要在你RegisterRoutes时,把MapHttpRoute修改为:
var route = routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
route.RouteHandler = new WebApiSessionRouteHandler();
现在再来看下/api/values的输出:"SessionID is 'me4exrjgv4lecvixa0ab2z1g'",发现session不在为null。
优化方案
为了在map route操作时,能够有一个统一的写法,可以增加一个扩展方法:
public static class HttpRouteExtensions
{
public static Route MapHttpRoute(this RouteCollection routes, string name, string routeTemplate, object defaults, IRouteHandler routeHandler)
{
object constraints = null;
HttpMessageHandler handler = null;
var route = routes.MapHttpRoute(name, routeTemplate, defaults, constraints, handler);
if (routeHandler != null)
{
route.RouteHandler = routeHandler;
}
return route;
}
}
这样,MapHttpRoute就可以改为:
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
routeHandler: new WebApiSessionRouteHandler()
);
结论
对HttpControllerHandler使用,不仅仅局限于是web api支持session。前面已经提到我们可以对web api的请求进行预处理,也可以创建自定义类,重现HttpControllerHandler中的:
1、BeginProcessRequest
2、EndProcessRequest
3、ProcessRequest
具体应该重写哪一个就需要根据具体的业务具体分析了。
web api中的RouteHandler的更多相关文章
- Web APi 2.0优点和特点?在Web APi中如何启动Session状态?
前言 曾几何时,微软基于Web服务技术给出最流行的基于XML且以扩展名为.asmx结尾的Web Service,此服务在.NET Framework中风靡一时同时也被.NET业界同仁所青睐,几年后在此 ...
- Entity Framework 6 Recipes 2nd Edition(9-3)译->找出Web API中发生了什么变化
9-3. 找出Web API中发生了什么变化 问题 想通过基于REST的Web API服务对数据库进行插入,删除和修改对象图,而不必为每个实体类编写单独的更新方法. 此外, 用EF6的Code Fri ...
- ASP.NET Web API中的Controller
虽然通过Visual Studio向导在ASP.NET Web API项目中创建的 Controller类型默认派生与抽象类型ApiController,但是ASP.NET Web API框架本身只要 ...
- 在ASP.NET Web API中使用OData
http://www.alixixi.com/program/a/2015063094986.shtml 一.什么是ODataOData是一个开放的数据协议(Open Data Protocol)在A ...
- Web Api中的get传值和post传值
GET 方式 get方式传参 我们一般用于获取数据做条件筛选,也就是 “查” 1.无参 var look = function () { $.ajax({ type: "GET", ...
- WEB API 中HTTP的get、post、put,delete 请求方式
一.WEB API 中HTTP 请求方式的四个主要方法 (GET, PUT, POST, DELETE), 按照下列方式映射为 CURD 操作: 1.POST 用于新建资源,服务端在指定的URI 上创 ...
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【五】——在Web Api中实现Http方法(Put,Post,Delete)
系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 在Web Api中,我们对资源的CRUD操作都是通过相应的Http方法来实现——Post(新 ...
- ASP.NET Web API 中的异常处理(转载)
转载地址:ASP.NET Web API 中的异常处理
- Web Api 中Get 和 Post 请求的多种情况分析
转自:http://www.cnblogs.com/babycool/p/3922738.html 来看看对于一般前台页面发起的get和post请求,我们在Web API中要如何来处理. 这里我使用J ...
随机推荐
- WebForms VS. MVC(翻译)
(本文翻译自CodeProject上阿三写的一篇文章,原文地址:http://www.codeproject.com/Articles/528117/WebForms-vs-MVC,讲了有关ASP.A ...
- 在JavaScript中对HTML进行反转义
在JavaScript中对字符串进行转义和反转义操作,常用的方法莫过于使用encodeURI (decodeURI).encodeURIComponent (decodeURIComponent)这几 ...
- Objective-C 观察者模式--简单介绍和使用
观察者模式(有时又被称为发布-订阅模式) 在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知. 这通常透过呼叫各观察者所提供的方法来实现.此种模式通常被用来实 ...
- 《Spark快速大数据分析》—— 第七章 在集群上运行Spark
- salesforce 零基础学习(四十三)运算取余
工作中遇到一个简单的小问题,判断两个数是否整除,如果不整除,获取相关的余数. 习惯java的我毫不犹豫的写下了代码 public Boolean isDivisibility(Integer divi ...
- 研究一下javascript的模块规范(CommonJs/AMD/CMD)
最近写react需要使用nodejs作为开发环境,需要通过npm安装一些第三方的依赖库,因此慢慢感觉到nodejs基础薄弱对我带来了一些不安全感,尤其是javascript模块这一块听到了很多概念,比 ...
- Hexo的Next主题配置
使用Next主题 在这里Downloads Next主题代码 将下载的代码放在myBlog/next目录下 设置站点myBlog/_config.yml的theme字段值为next 生成新页面hexo ...
- LINQ系列:Linq to Object排序操作符
LINQ排序操作符包括:OrderBy.OrderByDescending.ThenBy.ThenByDescending及Reverse. 1. OrderBy 1>. 原型定义 public ...
- 实战MEF(3):只导出类的成员
通过前面两篇文章的介绍,相信各位会明白MEF中有不少实用价值.上一文中我们也讨论了导入与导出,对于导出导入,今天我们再深入一点点,嗯,只是深入一点点而已,不会很难的,请大家务必放心,如果大家觉得看文章 ...
- Lightmaping
一.基本知识点 1.Baked Only:不会传入shader,只有烘焙时才有用,也就是_LightColor0等这种变量不会表示一个Baked Only Light(前提是场景有lightmap,如 ...