使用UAParser在C#MVC项目中如何判断用户是在用什么设备进行访问(手机,平板还是普通的电脑)

现在我们开发的很多web应用都要支持手机等移动设备。为了让手机用户能有更加好的用户体验,我们经常为手机设备专门准备一套前端的页面。这样当用户使用普通电脑来访问的时候,我们的应用就向用户展示普通电脑的页面。当用户使用手机等移动设备来访问我们的系统的时候,我们就向用户展示手机设备的页面。但是这时候另一个问题出现了。如何判断用户在使用什么设备访问我们的应用?是使用手机还是普通电脑?

网上能查到的不同的实现方式不少。我在这里也介绍一个我们最近在项目中采用的方法。

我们使用的是UAParser。UAParser是一个开源的项目,主要的功能是实现对各种用户useragent的解析。现在已经有很多种编程语言的实现。C#只是其中的一种。

为了方便大家理解,我在这里把主要的步骤和代码都写出来。

1) 用vs2013新建一个mvc的项目。

2) 使用nuget下载UAParser

3) 新建一个接口和实现它的类。

4) 代码

IUserAgent

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6.  
  7. namespace UserDeviceDetectWebApplication.Service
  8. {
  9. public interface IUserAgent
  10. {
  11. string RawValue { get; set; }
  12.  
  13. UserAgentInfo UserAgent { get; }
  14. DeviceInfo Device { get; }
  15. OSInfo OS { get; }
  16.  
  17. bool IsBot { get; }
  18. bool IsMobileDevice { get; }
  19. bool IsTablet { get; }
  20. //bool IsPdfConverter { get; }
  21. }
  22.  
  23. public sealed class DeviceInfo
  24. {
  25. public DeviceInfo(string family, bool isBot)
  26. {
  27. this.Family = family;
  28. this.IsBot = isBot;
  29. }
  30. public override string ToString()
  31. {
  32. return this.Family;
  33. }
  34. public string Family { get; private set; }
  35. public bool IsBot { get; private set; }
  36. }
  37.  
  38. public sealed class OSInfo
  39. {
  40. public OSInfo(string family, string major, string minor, string patch, string patchMinor)
  41. {
  42. this.Family = family;
  43. this.Major = major;
  44. this.Minor = minor;
  45. this.Patch = patch;
  46. this.PatchMinor = patchMinor;
  47. }
  48. public override string ToString()
  49. {
  50. var str = VersionString.Format(Major, Minor, Patch, PatchMinor);
  51. return (this.Family + (!string.IsNullOrEmpty(str) ? (" " + str) : null));
  52. }
  53. public string Family { get; private set; }
  54. public string Major { get; private set; }
  55. public string Minor { get; private set; }
  56. public string Patch { get; private set; }
  57. public string PatchMinor { get; private set; }
  58.  
  59. private static string FormatVersionString(params string[] parts)
  60. {
  61. return string.Join(".", (from v in parts
  62. where !string.IsNullOrEmpty(v)
  63. select v).ToArray<string>());
  64. }
  65. }
  66.  
  67. public sealed class UserAgentInfo
  68. {
  69. public UserAgentInfo(string family, string major, string minor, string patch)
  70. {
  71. this.Family = family;
  72. this.Major = major;
  73. this.Minor = minor;
  74. this.Patch = patch;
  75. }
  76. public override string ToString()
  77. {
  78. var str = VersionString.Format(Major, Minor, Patch);
  79. return (this.Family + (!string.IsNullOrEmpty(str) ? (" " + str) : null));
  80. }
  81. public string Family { get; private set; }
  82. public string Major { get; private set; }
  83. public string Minor { get; private set; }
  84. public string Patch { get; private set; }
  85. }
  86.  
  87. internal static class VersionString
  88. {
  89. public static string Format(params string[] parts)
  90. {
  91. return string.Join(".", (from v in parts
  92. where !string.IsNullOrEmpty(v)
  93. select v).ToArray<string>());
  94. }
  95. }
  96. }

UAParserUserAgent

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using uap = UAParser;
  6. using System.Text.RegularExpressions;
  7.  
  8. namespace UserDeviceDetectWebApplication.Service
  9. {
  10. public class UAParserUserAgent : IUserAgent
  11. {
  12. private readonly static uap.Parser s_uap;
  13. private static readonly Regex s_pdfConverterPattern = new Regex(@"wkhtmltopdf", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
  14.  
  15. # region Mobile UAs, OS & Devices
  16.  
  17. private static readonly HashSet<string> s_MobileOS = new HashSet<string>
  18. {
  19. "Android",
  20. "iOS",
  21. "Windows Mobile",
  22. "Windows Phone",
  23. "Windows CE",
  24. "Symbian OS",
  25. "BlackBerry OS",
  26. "BlackBerry Tablet OS",
  27. "Firefox OS",
  28. "Brew MP",
  29. "webOS",
  30. "Bada",
  31. "Kindle",
  32. "Maemo"
  33. };
  34.  
  35. private static readonly HashSet<string> s_MobileBrowsers = new HashSet<string>
  36. {
  37. "Android",
  38. "Firefox Mobile",
  39. "Opera Mobile",
  40. "Opera Mini",
  41. "Mobile Safari",
  42. "Amazon Silk",
  43. "webOS Browser",
  44. "MicroB",
  45. "Ovi Browser",
  46. "NetFront",
  47. "NetFront NX",
  48. "Chrome Mobile",
  49. "Chrome Mobile iOS",
  50. "UC Browser",
  51. "Tizen Browser",
  52. "Baidu Explorer",
  53. "QQ Browser Mini",
  54. "QQ Browser Mobile",
  55. "IE Mobile",
  56. "Polaris",
  57. "ONE Browser",
  58. "iBrowser Mini",
  59. "Nokia Services (WAP) Browser",
  60. "Nokia Browser",
  61. "Nokia OSS Browser",
  62. "BlackBerry WebKit",
  63. "BlackBerry", "Palm",
  64. "Palm Blazer",
  65. "Palm Pre",
  66. "Teleca Browser",
  67. "SEMC-Browser",
  68. "PlayStation Portable",
  69. "Nokia",
  70. "Maemo Browser",
  71. "Obigo",
  72. "Bolt",
  73. "Iris",
  74. "UP.Browser",
  75. "Minimo",
  76. "Bunjaloo",
  77. "Jasmine",
  78. "Dolfin",
  79. "Polaris",
  80. "Skyfire"
  81. };
  82.  
  83. private static readonly HashSet<string> s_MobileDevices = new HashSet<string>
  84. {
  85. "BlackBerry",
  86. "MI PAD",
  87. "iPhone",
  88. "iPad",
  89. "iPod",
  90. "Kindle",
  91. "Kindle Fire",
  92. "Nokia",
  93. "Lumia",
  94. "Palm",
  95. "DoCoMo",
  96. "HP TouchPad",
  97. "Xoom",
  98. "Motorola",
  99. "Generic Feature Phone",
  100. "Generic Smartphone"
  101. };
  102.  
  103. #endregion
  104.  
  105. private readonly HttpContextBase _httpContext;
  106.  
  107. private string _rawValue;
  108. private UserAgentInfo _userAgent;
  109. private DeviceInfo _device;
  110. private OSInfo _os;
  111.  
  112. private bool? _isBot;
  113. private bool? _isMobileDevice;
  114. private bool? _isTablet;
  115. private bool? _isPdfConverter;
  116.  
  117. static UAParserUserAgent()
  118. {
  119. s_uap = uap.Parser.GetDefault();
  120. }
  121.  
  122. public UAParserUserAgent(HttpContextBase httpContext)
  123. {
  124. this._httpContext = httpContext;
  125. }
  126.  
  127. public string RawValue
  128. {
  129. get
  130. {
  131. if (_rawValue == null)
  132. {
  133. if (_httpContext.Request != null)
  134. {
  135. _rawValue = _httpContext.Request.UserAgent.ToString();
  136. }
  137. else
  138. {
  139. _rawValue = "";
  140. }
  141. }
  142.  
  143. return _rawValue;
  144. }
  145. // for (unit) test purpose
  146. set
  147. {
  148. _rawValue = value;
  149. _userAgent = null;
  150. _device = null;
  151. _os = null;
  152. _isBot = null;
  153. _isMobileDevice = null;
  154. _isTablet = null;
  155. _isPdfConverter = null;
  156. }
  157. }
  158.  
  159. public virtual UserAgentInfo UserAgent
  160. {
  161. get
  162. {
  163. if (_userAgent == null)
  164. {
  165. var tmp = s_uap.ParseUserAgent(this.RawValue);
  166. _userAgent = new UserAgentInfo(tmp.Family, tmp.Major, tmp.Minor, tmp.Patch);
  167. }
  168. return _userAgent;
  169. }
  170. }
  171.  
  172. public virtual DeviceInfo Device
  173. {
  174. get
  175. {
  176. if (_device == null)
  177. {
  178. var tmp = s_uap.ParseDevice(this.RawValue);
  179. _device = new DeviceInfo(tmp.Family, tmp.IsSpider);
  180. }
  181. return _device;
  182. }
  183. }
  184.  
  185. public virtual OSInfo OS
  186. {
  187. get
  188. {
  189. if (_os == null)
  190. {
  191. var tmp = s_uap.ParseOS(this.RawValue);
  192. _os = new OSInfo(tmp.Family, tmp.Major, tmp.Minor, tmp.Patch, tmp.PatchMinor);
  193. }
  194. return _os;
  195. }
  196. }
  197.  
  198. public virtual bool IsBot
  199. {
  200. get
  201. {
  202. if (!_isBot.HasValue)
  203. {
  204. _isBot = _httpContext.Request.Browser.Crawler || this.Device.IsBot;
  205. }
  206. return _isBot.Value;
  207. }
  208. }
  209.  
  210. public virtual bool IsMobileDevice
  211. {
  212. get
  213. {
  214. if (!_isMobileDevice.HasValue)
  215. {
  216. _isMobileDevice =
  217. s_MobileOS.Contains(this.OS.Family) ||
  218. s_MobileBrowsers.Contains(this.UserAgent.Family) ||
  219. s_MobileDevices.Contains(this.Device.Family);
  220. }
  221. return _isMobileDevice.Value;
  222. }
  223. }
  224.  
  225. public virtual bool IsTablet
  226. {
  227. get
  228. {
  229. if (!_isTablet.HasValue)
  230. {
  231. _isTablet =
  232. Regex.IsMatch(this.Device.Family, "iPad|Kindle Fire|Nexus 10|Xoom|Transformer|MI PAD|IdeaTab", RegexOptions.CultureInvariant) ||
  233. this.OS.Family == "BlackBerry Tablet OS";
  234. }
  235. return _isTablet.Value;
  236. }
  237. }
  238.  
  239. public virtual bool IsPdfConverter
  240. {
  241. get
  242. {
  243. if (!_isPdfConverter.HasValue)
  244. {
  245. _isPdfConverter = s_pdfConverterPattern.IsMatch(this.RawValue);
  246. }
  247. return _isPdfConverter.Value;
  248. }
  249. }
  250.  
  251. }
  252. }

5) 修改HomeController.cs

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using System.Web.Mvc;
  6. using UserDeviceDetectWebApplication.Service;
  7. using System.Diagnostics;
  8.  
  9. namespace UserDeviceDetectWebApplication.Controllers
  10. {
  11. public class HomeController : Controller
  12. {
  13. public ActionResult Index()
  14. {
  15. UAParserUserAgent userAgent = new UAParserUserAgent(this.HttpContext);
  16.  
  17. ViewBag.Os= userAgent.OS.ToString();
  18. ViewBag.Device = userAgent.Device.ToString();
  19. ViewBag.Agent = userAgent.UserAgent.ToString();
  20. ViewBag.RawValue = userAgent.RawValue.ToString();
  21.  
  22. Debug.WriteLine("user os: "+userAgent.OS.ToString());
  23. Debug.WriteLine("user Device: " + userAgent.Device.ToString());
  24. Debug.WriteLine("user Agent: " + userAgent.UserAgent.ToString());
  25. Debug.WriteLine("user RawValue: " + userAgent.RawValue.ToString());
  26.  
  27. if (userAgent.IsMobileDevice)
  28. {
  29. Debug.WriteLine("这是一个手机");
  30. ViewBag.MobilePc = "手机";
  31. }
  32.  
  33. else if (userAgent.IsTablet)
  34. {
  35. ViewBag.MobilePc = "平板";
  36. Debug.WriteLine("这是一个平板");
  37. }
  38.  
  39. else
  40. {
  41. ViewBag.MobilePc = "普通电脑";
  42. Debug.WriteLine("这是一个普通电脑");
  43. }
  44.  
  45. return View();
  46. }
  47.  
  48. }
  49. }

6) 修改views\home\Index.cshtml

  1. @{
  2. Layout = null;
  3. ViewBag.Title = "Home Page";
  4. }
  5.  
  6. <p>
  7. 用户的 操作系统:@ViewBag.Os</br>
  8. 用户的设备: @ViewBag.Device </br>
  9. 用户的浏览器: @ViewBag.Agent </br>
  10. 原始的用户访问设备信息: @ViewBag.RawValue </br>
  11. 用户使用的是 @ViewBag.MobilePc </br>
  12. </p>

7) 编译我们的程序,运行它。试着用不同的浏览器,不同的手机访问http://localhost:62526/Home/Index。端口号你的环境可能和我的不一样哦。如果你不知道如何运行mvc的web程序,可以咨询我哦。

欢迎大家指正和讨论。

 

MVC项目中如何判断用户是在用什么设备进行访问的更多相关文章

  1. 使用UAParser在C#MVC项目中如何判断用户是在用什么设备进行访问(手机,平板还是普通的电脑)

    现在我们开发的很多web应用都要支持手机等移动设备.为了让手机用户能有更加好的用户体验,我们经常为手机设备专门准备一套前端的页面.这样当用户使用普通电脑来访问的时候,我们的应用就向用户展示普通电脑的页 ...

  2. 谈谈MVC项目中的缓存功能设计的相关问题

    本文收集一些关于项目中为什么需要使用缓存功能,以及怎么使用等,在实际开发中对缓存的设计的考虑 为什么需要讨论缓存呢? 缓存是一个中大型系统所必须考虑的问题.为了避免每次请求都去访问后台的资源(例如数据 ...

  3. 在ASP.NET MVC项目中使用极验验证(geetest)

    时间 2016-03-02 18:22:37 smallerpig 原文  http://www.smallerpig.com/979.html 主题 ASP.NET MVC   geetest开发体 ...

  4. 转 mvc项目中,解决引用jquery文件后智能提示失效的办法

    mvc项目中,解决用Url.Content方法引用jquery文件后智能提示失效的办法   这个标题不知道要怎么写才好, 但是希望文章的内容对大家有帮助. 场景如下: 我们在用开发开发程序的时候,经常 ...

  5. 在 ASP.NET MVC 项目中使用 WebForm、 HTML

    原文地址:http://www.cnblogs.com/snowdream/archive/2009/04/17/winforms-in-mvc.html ASP.NET MVC和WebForm各有各 ...

  6. 在已有的Asp.net MVC项目中引入Taurus.MVC

    Taurus.MVC是一个优秀的框架,如果要应用到已有的Asp.net MVC项目中,需要修改一下. 1.前提约定: 走Taurus.MVC必须指定后缀.如.api 2.原项目修改如下: web.co ...

  7. ASP.NET MVC项目中App_Code目录在程序应用

    学习ASP.NET MVC,如果你是开发ASP.NET MVC项目的,也许你去为项目添加前ASP.NET项目的APP_Code目录,在这里创建与添加的Class类,也许你无法在MVC项目所引用. 那这 ...

  8. ssm项目中遇到微信用户名称带有表情,插入失败问题

    ssm项目中遇到微信用户名称带有表情,插入失败问题 问题 Mysql的utf8编码最多3个字节,而Emoji表情或者某些特殊字符是4个字节. 因此会导致带有表情的昵称插入数据库时出错. 解决方法 一. ...

  9. 如何在mvc项目中使用apiController

    文章地址:How do you route from an MVC project to an MVC ApiController in another project? 文章地址:How to Us ...

随机推荐

  1. Mysql 学习记录

    ( xampp 的mysql 与 直接用 dnf 安装的 mysql 有冲突! ) 1. 数据库基本知识: 一张表的行 又称为 记录 一张表的列 又称为 字段 表结构:所有字段,规定了你的每一条记录所 ...

  2. C++学习笔记6

    泛型算法 1. 算法怎样工作 每一个泛型算法的实现都独立于单独的容器.这些算法还是大而不全的,而且不依赖于容器存储的元素类型.为了知道算法怎样工作,让我们深入了解find 操作.该操作的任务是在一个未 ...

  3. [HDU 4741]Save Labman No.004[计算几何][精度]

    题意: 求两条空间直线的距离,以及对应那条距离线段的两端点坐标. 思路: 有一个参数方程算最短距离的公式, 代入求即可. 但是这题卡精度... 用另外的公式(先算出a直线上到b最近的点p的坐标, 再算 ...

  4. WebApi个人理解概要

    WebApi概要 Global文件的作用: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class MvcApplication : System.We ...

  5. Unity cg vertex and fragment shaders(一)

    cg片段 Cg程序片段写CGPROGRAM和ENDCG之间 开始时的片段可以作为#pragma语句编译指令 Pass { // ... the usual pass state setup ... C ...

  6. Dos关闭进程命令

    netstat -ao 查找占用端口的进程 taskkikk /pid 端口pid  /f

  7. Struts学习之自定义结果集

    转自:http://blog.csdn.net/hanxuemin12345/article/details/38763057 项目中我们经常遇到这样的需求——页面部分刷新,例如:添加用户,转到添加用 ...

  8. [LeetCode]题解(python):117-Populating Next Right Pointers in Each Node II

    题目来源: https://leetcode.com/problems/populating-next-right-pointers-in-each-node-ii/ 题意分析: 根据上一题,如果给定 ...

  9. [转] iOS多线程编程之Grand Central Dispatch(GCD)介绍和使用

    介绍: Grand Central Dispatch 简称(GCD)是苹果公司开发的技术,以优化的应用程序支持多核心处理器和其他的对称多处理系统的系统.这建立在任务并行执行的线程池模式的基础上的.它首 ...

  10. Matplotlib中文乱码

    想要分析一批数据,画出图形会比较直观.所以就搜索了一下各种软件,最终选择使用python的matplotlib.原因也是因为python使用起来比较方便,虽然R才是分析数据的首选,不过,没有R的基础, ...