MVC项目中如何判断用户是在用什么设备进行访问

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

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

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

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

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

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

2) 使用nuget下载UAParser

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

4) 代码

IUserAgent

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace UserDeviceDetectWebApplication.Service
{
    public interface IUserAgent
    {
        string RawValue { get; set; }

        UserAgentInfo UserAgent { get; }
        DeviceInfo Device { get; }
        OSInfo OS { get; }

        bool IsBot { get; }
        bool IsMobileDevice { get; }
        bool IsTablet { get; }
        //bool IsPdfConverter { get; }
    }

    public sealed class DeviceInfo
    {
        public DeviceInfo(string family, bool isBot)
        {
            this.Family = family;
            this.IsBot = isBot;
        }
        public override string ToString()
        {
            return this.Family;
        }
        public string Family { get; private set; }
        public bool IsBot { get; private set; }
    }

    public sealed class OSInfo
    {
        public OSInfo(string family, string major, string minor, string patch, string patchMinor)
        {
            this.Family = family;
            this.Major = major;
            this.Minor = minor;
            this.Patch = patch;
            this.PatchMinor = patchMinor;
        }
        public override string ToString()
        {
            var str = VersionString.Format(Major, Minor, Patch, PatchMinor);
            return (this.Family + (!string.IsNullOrEmpty(str) ? (" " + str) : null));
        }
        public string Family { get; private set; }
        public string Major { get; private set; }
        public string Minor { get; private set; }
        public string Patch { get; private set; }
        public string PatchMinor { get; private set; }

        private static string FormatVersionString(params string[] parts)
        {
            return string.Join(".", (from v in parts
                                     where !string.IsNullOrEmpty(v)
                                     select v).ToArray<string>());
        }
    }

    public sealed class UserAgentInfo
    {
        public UserAgentInfo(string family, string major, string minor, string patch)
        {
            this.Family = family;
            this.Major = major;
            this.Minor = minor;
            this.Patch = patch;
        }
        public override string ToString()
        {
            var str = VersionString.Format(Major, Minor, Patch);
            return (this.Family + (!string.IsNullOrEmpty(str) ? (" " + str) : null));
        }
        public string Family { get; private set; }
        public string Major { get; private set; }
        public string Minor { get; private set; }
        public string Patch { get; private set; }
    }

    internal static class VersionString
    {
        public static string Format(params string[] parts)
        {
            return string.Join(".", (from v in parts
                                     where !string.IsNullOrEmpty(v)
                                     select v).ToArray<string>());
        }
    }
}

UAParserUserAgent

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using uap = UAParser;
using System.Text.RegularExpressions;

namespace UserDeviceDetectWebApplication.Service
{
    public class UAParserUserAgent : IUserAgent
    {
        private readonly static uap.Parser s_uap;
        private static readonly Regex s_pdfConverterPattern = new Regex(@"wkhtmltopdf", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);

        # region Mobile UAs, OS & Devices

        private static readonly HashSet<string> s_MobileOS = new HashSet<string>
        {
            "Android",
            "iOS",
            "Windows Mobile",
            "Windows Phone",
            "Windows CE",
            "Symbian OS",
            "BlackBerry OS",
            "BlackBerry Tablet OS",
            "Firefox OS",
            "Brew MP",
            "webOS",
            "Bada",
            "Kindle",
            "Maemo"
        };

        private static readonly HashSet<string> s_MobileBrowsers = new HashSet<string>
        {
            "Android",
            "Firefox Mobile",
            "Opera Mobile",
            "Opera Mini",
            "Mobile Safari",
            "Amazon Silk",
            "webOS Browser",
            "MicroB",
            "Ovi Browser",
            "NetFront",
            "NetFront NX",
            "Chrome Mobile",
            "Chrome Mobile iOS",
            "UC Browser",
            "Tizen Browser",
            "Baidu Explorer",
            "QQ Browser Mini",
            "QQ Browser Mobile",
            "IE Mobile",
            "Polaris",
            "ONE Browser",
            "iBrowser Mini",
            "Nokia Services (WAP) Browser",
            "Nokia Browser",
            "Nokia OSS Browser",
            "BlackBerry WebKit",
            "BlackBerry", "Palm",
            "Palm Blazer",
            "Palm Pre",
            "Teleca Browser",
            "SEMC-Browser",
            "PlayStation Portable",
            "Nokia",
            "Maemo Browser",
            "Obigo",
            "Bolt",
            "Iris",
            "UP.Browser",
            "Minimo",
            "Bunjaloo",
            "Jasmine",
            "Dolfin",
            "Polaris",
            "Skyfire"
        };

        private static readonly HashSet<string> s_MobileDevices = new HashSet<string>
        {
            "BlackBerry",
            "MI PAD",
            "iPhone",
            "iPad",
            "iPod",
            "Kindle",
            "Kindle Fire",
            "Nokia",
            "Lumia",
            "Palm",
            "DoCoMo",
            "HP TouchPad",
            "Xoom",
            "Motorola",
            "Generic Feature Phone",
            "Generic Smartphone"
        };

        #endregion

        private readonly HttpContextBase _httpContext;

        private string _rawValue;
        private UserAgentInfo _userAgent;
        private DeviceInfo _device;
        private OSInfo _os;

        private bool? _isBot;
        private bool? _isMobileDevice;
        private bool? _isTablet;
        private bool? _isPdfConverter;

        static UAParserUserAgent()
        {
            s_uap = uap.Parser.GetDefault();
        }

        public UAParserUserAgent(HttpContextBase httpContext)
        {
            this._httpContext = httpContext;
        }

        public string RawValue
        {
            get
            {
                if (_rawValue == null)
                {
                    if (_httpContext.Request != null)
                    {
                        _rawValue = _httpContext.Request.UserAgent.ToString();
                    }
                    else
                    {
                        _rawValue = "";
                    }
                }

                return _rawValue;
            }
            // for (unit) test purpose
            set
            {
                _rawValue = value;
                _userAgent = null;
                _device = null;
                _os = null;
                _isBot = null;
                _isMobileDevice = null;
                _isTablet = null;
                _isPdfConverter = null;
            }
        }

        public virtual UserAgentInfo UserAgent
        {
            get
            {
                if (_userAgent == null)
                {
                    var tmp = s_uap.ParseUserAgent(this.RawValue);
                    _userAgent = new UserAgentInfo(tmp.Family, tmp.Major, tmp.Minor, tmp.Patch);
                }
                return _userAgent;
            }
        }

        public virtual DeviceInfo Device
        {
            get
            {
                if (_device == null)
                {
                    var tmp = s_uap.ParseDevice(this.RawValue);
                    _device = new DeviceInfo(tmp.Family, tmp.IsSpider);
                }
                return _device;
            }
        }

        public virtual OSInfo OS
        {
            get
            {
                if (_os == null)
                {
                    var tmp = s_uap.ParseOS(this.RawValue);
                    _os = new OSInfo(tmp.Family, tmp.Major, tmp.Minor, tmp.Patch, tmp.PatchMinor);
                }
                return _os;
            }
        }

        public virtual bool IsBot
        {
            get
            {
                if (!_isBot.HasValue)
                {
                    _isBot = _httpContext.Request.Browser.Crawler || this.Device.IsBot;
                }
                return _isBot.Value;
            }
        }

        public virtual bool IsMobileDevice
        {
            get
            {
                if (!_isMobileDevice.HasValue)
                {
                    _isMobileDevice =
                        s_MobileOS.Contains(this.OS.Family) ||
                        s_MobileBrowsers.Contains(this.UserAgent.Family) ||
                        s_MobileDevices.Contains(this.Device.Family);
                }
                return _isMobileDevice.Value;
            }
        }

        public virtual bool IsTablet
        {
            get
            {
                if (!_isTablet.HasValue)
                {
                    _isTablet =
                        Regex.IsMatch(this.Device.Family, "iPad|Kindle Fire|Nexus 10|Xoom|Transformer|MI PAD|IdeaTab", RegexOptions.CultureInvariant) ||
                        this.OS.Family == "BlackBerry Tablet OS";
                }
                return _isTablet.Value;
            }
        }

        public virtual bool IsPdfConverter
        {
            get
            {
                if (!_isPdfConverter.HasValue)
                {
                    _isPdfConverter = s_pdfConverterPattern.IsMatch(this.RawValue);
                }
                return _isPdfConverter.Value;
            }
        }

    }
}

5) 修改HomeController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using UserDeviceDetectWebApplication.Service;
using System.Diagnostics;

namespace UserDeviceDetectWebApplication.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            UAParserUserAgent userAgent = new UAParserUserAgent(this.HttpContext);

            ViewBag.Os= userAgent.OS.ToString();
            ViewBag.Device = userAgent.Device.ToString();
            ViewBag.Agent = userAgent.UserAgent.ToString();
            ViewBag.RawValue = userAgent.RawValue.ToString();

            Debug.WriteLine("user os: "+userAgent.OS.ToString());
            Debug.WriteLine("user Device: " + userAgent.Device.ToString());
            Debug.WriteLine("user Agent: " + userAgent.UserAgent.ToString());
            Debug.WriteLine("user RawValue: " + userAgent.RawValue.ToString());

            if (userAgent.IsMobileDevice)
            {
                Debug.WriteLine("这是一个手机");
                ViewBag.MobilePc = "手机";
            }

            else if (userAgent.IsTablet)
            {
                ViewBag.MobilePc = "平板";
                Debug.WriteLine("这是一个平板");
            }

            else
            {
                ViewBag.MobilePc = "普通电脑";
                Debug.WriteLine("这是一个普通电脑");
            }

            return View();
        }

    }
}

6) 修改views\home\Index.cshtml

@{
    Layout = null;
    ViewBag.Title = "Home Page";
}

<p>
    用户的 操作系统:@ViewBag.Os</br>
    用户的设备: @ViewBag.Device </br>
    用户的浏览器: @ViewBag.Agent </br>
    原始的用户访问设备信息: @ViewBag.RawValue </br>
    用户使用的是 @ViewBag.MobilePc </br>
</p>

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

欢迎大家指正和讨论。

分类: .Net MVC Entity FrameWork知识点探讨

时间: 2024-10-12 14:33:57

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

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

本文收集一些关于项目中为什么需要使用缓存功能,以及怎么使用等,在实际开发中对缓存的设计的考虑 为什么需要讨论缓存呢? 缓存是一个中大型系统所必须考虑的问题.为了避免每次请求都去访问后台的资源(例如数据库),我们一般会考虑将一些更新不是很频繁的,可以重用的数据,通过一定的方式临时地保存起来,后续的请求根据情况可以直接访问这些保存起来的数据.这种机制就是所谓的缓存机制. 根据缓存的位置不同,可以区分为: 1.客户端缓存(缓存在用户的客户端,例如浏览器) 2.服务器断货(缓存在服务器中,可以缓存在内存

在VS2013 MVC项目中上传图片

之前做网站项目时,凡遇到保存图片的,我都将图片上传后存储在服务器的本地文件夹中,在一个Controller的Action中,类似操作如下所示: public ActionResult UpLoad(HttpPostedFileBasearImg) {             //保存图片            if (arImg != null)            {                 string uploadName =arImg.FileName;//获取待上传图片的完整

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

原文地址:http://www.cnblogs.com/snowdream/archive/2009/04/17/winforms-in-mvc.html ASP.NET MVC和WebForm各有各的优点,我们可能需要同时使用ASP.NET MVC和WebForm.本文介绍了如何在ASP.NET MVC项目中使用WebForm.首先新建一个名为WebForms的文件夹用于存放WebForm,并添加一个Web窗体文件Demo.aspx作为演示. Demo.aspx就简单的输出一句话“It’s a

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

mvc项目中,解决用Url.Content方法引用jquery文件后智能提示失效的办法 这个标题不知道要怎么写才好, 但是希望文章的内容对大家有帮助. 场景如下: 我们在用开发开发程序的时候,经常会引用jquery, 但是由于路由的关系,最终访问页面的地址相对js文件来说,是不固定的. 为了在view中能够引用到jquery文件,我们通常都是用如下的代码 <script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")

【转】在 ASP.NET MVC 项目中使用 WebForm

ASP.NET MVC和WebForm各有各的优点,我们可能需要同时使用ASP.NET MVC和WebForm.本文介绍了如何在ASP.NET MVC项目中使用WebForm. 首先新建一个名为WebForms的文件夹用于存放WebForm,并添加一个Web窗体文件Demo.aspx作为演示. Demo.aspx就简单的输出一句话"It's a WebForm." 关键步骤在于路由设置.如果你希望WebForms这个文件夹名作为URL的一部分,也就是普通WebForm应用程序的方式来访

ServiceStack 项目实例 005 使用第一个服务功能 (在MVC项目中)

建立好服务后,我们就可以在MVC项目中使用这个服务,在使用这个服务之前,需要先确定一下它所在端口,只需要在SS项目上点右键,将其设置为启动项目,然后运行一下SS项目,在浏览器地址栏,就可以看到这个服务的端口号,并且也能看到已经添加到其中的服务.(运行的效果可以在001节中的截图看到,001节中的端口为59068.) 在MVC的Controller目录下添加一个控制器NewsController.cs,在NewsController.cs中加入一个 Action, 用来显示添加新闻的页面 publ

添加Bootstrap 到MVC项目中(vs2010)

环境:Visual Studio 2010   ASP.NET MVC3 手动添加: 下载地址:http://twitter.github.com/bootstrap/ 一个js,两个css,两张图 js 文件:  •bootstrap.min.js CSS 文件:  •bootstrap.min.css  •bootstrap-responsive.min.css image 文件:  •glyphicons-halflings.png  •glyphicons-halflings-white

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

学习ASP.NET MVC,如果你是开发ASP.NET MVC项目的,也许你去为项目添加前ASP.NET项目的APP_Code目录,在这里创建与添加的Class类,也许你无法在MVC项目所引用. 那这样说,是不是一没有作用了呢?非也. 从下面一步一步来学习. 创建一个model,名称:Machine using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace Insu

关于MVC项目中的主管放行

一线程序员和 sa 总是相恨相杀,这话确实不假,吐槽这里就不多讲,项目快开发完的时候,让之前各个模块的增删改操作全部都先放入对应的临时表(增加一状态栏位Status,来表示增.删.改)中,然后在主管放行界面放行之后,数据才算真正入库.sa 轻轻一句话,整个项目几乎从头到尾要改一遍.虽然已不是第一次做此事.但着实还是费了一番气力.期间遇到了不少问题很值得记录. 流程大致如上,第一排是原逻辑,第二排是增加主管放行的新逻辑(随手画的,比较简陋) 原项目中涉及到,多表主外键关系,新增范本功能等较为复杂的