asp.net mvc让我告诉你请求从哪里来
移动互联网的兴起,导致越来越多的网站开始看中自己的mobile站点(m站),例如我们用手机浏览器访问58,美团等网站都会看到适配的m站点,随之而来响应式布局,h5等技术随之兴起,对于一些大型网站来说,可能会投入专门的人力来研发,对于一些小型网站,或者个人网站为了更好的浏览体验可能在你用移动设备访问时候给你转到一个H5适配页面,对网站进行一些介绍引导用户注册app等。
本章目的:利用MVC的路由以便你的网站在用移动设备浏览时候指定到相应H5或者mobile页面,完善体验.
HTTP协议中UserAgent
快速简洁,我们需要找到能帮助我们区分当前请求来源的部分
(1.1)HTTP协议详解之消息报头篇->UserAgent
用户代理 User Agent,是指浏览器,它的信息包括硬件平台、系统软件、应用软件和用户个人偏好。在X.400电子系统中,用户代理是一种对数据打包、创造分组头,以及编址、传递消息的部件。用户代理并不是仅指浏览器,还包括搜索引擎。当前文章主要指浏览器中
(1.2)UserAgent举例说明
我们上网登陆论坛的时候,往往会看到一些欢迎信息,其中列出了你的操作系统的名称和版本,你所使用的浏览器的名称和版本,这往往让很多人感到很神奇,实际上,服务器应用程序就是从User-Agent这个请求报头域中获取到这些信息。User-Agent请求报头域允许客户端将它的操作系统、浏览器和其它属性告诉服务器。大家看一下下边的例子

举例我的几个测试:大家按照我截图的就可以观察到相应的不同
(1)apple iphone6
User-Agent:Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.3 (KHTML, like Gecko) Version/8.0 Mobile/12A4345d Safari/600.1.4
(2)Samsung Galaxy Note3
User-Agent:Mozilla/5.0 (Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
(3)Nokia Lumia520
User-Agent:Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 520)
(4)PC浏览器
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.23
MVC中处理请求,判别请求来源
说到asp.net mvc我们最先想到的就是 路由系统,或者filter,目标只有一个,就是找到一个在请求处理管道靠前的位置来判断请求,进行相应url重写,请求来自pc,网站指向PC站点,请求来自mobile网站指向mobile站点。
(2.1)梳理一下mvc路由流程
引用蒋老师的话,HttpModule和httpHandler是asp.net管道的两个重要组件,请求的最终处理通过Handler来完成,asp.net mvc就是通过一个名为mvcHandler的自定义httpHandler实现了对controller的激活和acion的执行,但是在这之前对controller和action的解析是通过asp.net mvc的url路由系统完成的,而整个url路由系统是通过一个名为urlRoutingModule的自定义httpModule实现的。
(2.2)流程图

我们思路在路由的层面,通过userAgent进行判定,将所有来自移动设备请求转到我们mobile页面的控制器
(2.3)项目实践
(1)新建一个mvc项目,创建一个pc index和一个mobile index页面
pc首页:HomeController
mobile首页:MobileController

(2)编写路由规则
新建urlProvider继承RouteBase重写GetRouteData方法用来判断userAgent
public override RouteData GetRouteData(HttpContextBase httpContext)
{
string agent = httpContext.Request.UserAgent;
//Mobile HttpRequest User-Agent 通过上边总结出的关键字
string[] keywords = { "Android", "iPhone", "iPod", "Windows Phone", "MQQBrowser" }; //下边逻辑:1:请求PC的控制器 2:请求来自移动设备
if (!httpContext.Request.RawUrl.ToLower().Contains("/mobile/"))
{
foreach (string item in keywords)
{
if (agent.ToLower().Contains(item.ToLower()))
{
//如果是从移动设备访问该PC站点统一跳转到mobile首页
var data = new RouteData(this, new MvcRouteHandler());
data.Values.Add("controller", "Mobile");
data.Values.Add("action", "Index");
return data;
} }
}
return null;
}
(3)注册我们自定义的路由重写规则Global.asax
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.Add(new UrlProvider()); //我们自定义的规则 routes.MapRoute(
"Default", // 路由名称
"{controller}/{action}/{id}", // 带有参数的 URL
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 参数默认值
); }
(4)进行测试
直接通过浏览器模拟PC访问

我们用谷歌最新版本手机模式浏览 PC主页Home/index,我们期望的结果是返回的Mobile页面
下图结果我们可以看到虽然地址是PC的地址,但是返回的效果是我们的Mobile页面。

总结:
(1)这是一篇很纠结的博客,因为自己的方案不是常规的,某种程度手机的页面或许只能放在mobile控制器下,所以我给这篇文章定位为小型网站希望增加移动设备访问页面的一种折中办法。也可以当做一篇了解http协议中userAgent这一属性的讲解。
(2)个人认为好的方案是通过nginx服务器(负载服务器)判定请求来源,apache服务器也有类似功能。然后转到相应的pc站点或者m站点,当然如果你有更好的方案或者你们的项目中有更好的方案可以分享一下。
(3)回归本源,无论是在服务器判断还是在程序中判断,我们区别的方法还是通过http,最终定位到userAgent。
(4)这里感谢群友大哥:萧秦的建议 mvc中的全局过滤器GlobalFilterCollection也可以实现对请求拦截判定,也可以用FilterProvider去添加,总之原理都是通过对请求拦截,判断userAgent
文章代码地址
http://files.cnblogs.com/files/mongo/MT.WebApp.zip
asp.net mvc让我告诉你请求从哪里来的更多相关文章
- [转]ASP.NET MVC学习系列(二)-WebAPI请求 传参
[转]ASP.NET MVC学习系列(二)-WebAPI请求 传参 本文转自:http://www.cnblogs.com/babycool/p/3922738.html ASP.NET MVC学习系 ...
- ASP.NET MVC 实现AJAX跨域请求方法《1》
ASP.NET MVC 实现AJAX跨域请求的两种方法 通常发送AJAX请求都是在本域内完成的,也就是向本域内的某个URL发送请求,完成部分页面的刷新.但有的时候需要向其它域发送AJAX请求,完成数据 ...
- ASP.NET MVC 实现 AJAX 跨域请求
ASP.NET MVC 实现AJAX跨域请求的两种方法 和大家分享下Ajax 跨域的经验,之前也找了好多资料,但是都不行,后来看到个可行的修改了并测试下 果然OK了 希望对大家有所帮助! 通常发送 ...
- ASP.NET MVC学习系列(二)-WebAPI请求
继续接着上文 ASP.NET MVC学习系列(一)-WebAPI初探 来看看对于一般前台页面发起的get和post请求,我们在Web API中要如何来处理. 这里我使用Jquery 来发起异步请求实现 ...
- ASP.NET MVC学习系列(二)-WebAPI请求(转)
转自:http://www.cnblogs.com/babycool/p/3922738.html 继续接着上文 ASP.NET MVC学习系列(一)-WebAPI初探 来看看对于一般前台页面发起的g ...
- ASP.NET MVC学习系列(二)-WebAPI请求 转载https://www.cnblogs.com/babycool/p/3922738.html
继续接着上文 ASP.NET MVC学习系列(一)-WebAPI初探 来看看对于一般前台页面发起的get和post请求,我们在Web API中要如何来处理. 这里我使用Jquery 来发起异步请求实现 ...
- ASP.NET MVC 实现AJAX跨域请求的两种方法
通常发送AJAX请求都是在本域内完成的,也就是向本域内的某个URL发送请求,完成部分页面的刷新.但有的时候需要向其它域发送AJAX请求,完成数据的加载,例如Google. 在ASP.NET MVC 框 ...
- ASP.NET MVC中防止跨站请求攻击(CSRF)
转载 http://kevintsengtw.blogspot.co.nz/2013/01/aspnet-mvc-validateantiforgerytoken.html 在 ASP.NET M ...
- asp.net MVC中防止跨站请求攻击(CSRF)的ajax用法
参考: Preventing Cross-Site Request Forgery (CSRF) AttacksValidating .NET MVC 4 anti forgery tokens in ...
随机推荐
- STL笔记(2) STL之父访谈录
年3月,dr.dobb's journal特约记者, 著名技术书籍作家al stevens采访了stl创始人alexander stepanov. 这份访谈纪录是迄今为止对于stl发展历史的最完备介绍 ...
- hdu4760Good Firewall
4760 数组模拟就可以了 读的时候可以整数读入 #include <iostream> #include<cstdio> #include<cstring> #i ...
- SQLite及ORMlite在WebApp中的使用
Spring 配置 下面的databaseUrl在windows下,指向了c:/user/yourhome路径,暂时没想到怎么配置到WEBAPP根路径下. 因为是轻量级工控webapp,数据库规模不大 ...
- System.Linq.Dynamic 和Nhibernate
var session = NHibernateSessionManager.Instance.GetSession(); "); var staffList = session.Query ...
- HDU 3790 最短路径问题【Dijkstra】
题意:给出n个点,m条边,每条边的长度d和花费p,给出起点和终点的最短距离和花费,求最短距离,如果有多个最短距离,输出花费最少的 在用dijkstra求最短距离的时候,再用一个f[]数组保存下最少花费 ...
- I.MX6 Android backlight modify by C demo
/************************************************************************** * I.MX6 Android backligh ...
- jquery中html()/text()/val()区别
html就是你可以添加<span></span><li></li>的标记text只能写文本如果写了上面的标记则会以文本形式输出,就是输出标签体的内容va ...
- hibernate中使用fetch来决策性能方案
什么时候用子查询,或者连接查询 一般多个数据的对应用子查询,单一行的数据用连接 (若要查询每个学生分别学了什么课程 ,若要fetch=join.fetch=select) 则是这种情况 Hiberna ...
- c++ vector 释放内存
1.释放单个指针 关于Vector中存放指针的问题,在进行清空的时候比较安全的一种做法是: std::vector<ClassName *> ClassNameVec; ... ...
- 【转】linux设备驱动程序中的阻塞机制
原文网址:http://www.cnblogs.com/geneil/archive/2011/12/04/2275272.html 阻塞与非阻塞是设备访问的两种方式.在写阻塞与非阻塞的驱动程序时,经 ...