[转载]Asp.NET MVC Widget开发 – Mobile支持 – Creative dream – 博客园.
在ASP.NET开发博客类系统,我们经常都会用到Widget,像在线好友、最近访问 好友、最新留言等,关于ASP.NET MVC与Asp.NET视图的差异,这里不再说了,大家可去查一下,接下来我以“我的好友”列表来要介绍在Asp.NET MVC实现这一功能以及结构设计。
- 开发工具:VS 2010 EN
- 开发语言:Visual C#
- ASP.NET MVC 3
- Windows Phone 7 Emulator
- Asp.NET MVC Widget – 设计
- Asp.NET MVC Widget – Controller控制器
- Asp.NET MVC Widget – ViewEngine
- Asp.NET MVC Widget – Mobile支持
前3篇中已经讲了Widget实现方法,并用“我的好友”实例做了演示,接下来将要支持Mobile了。
1. 先来贴下”widgets”的目录结构
/Mobile 存放Mobile支持的页面文件
/Mobile/Widget.cshtml 通用的Mobile显示页面,即任何手机客户端未找到情况下,调用此显示
/Mobile/iPhone/ 存放针对iPhone类型文件
/Mobile/iPhone/Widget.cshtml iPhone主页面文件
/Mobile/WindowsMobile 存放针对WindowsMobile类型文件
/Mobile/WindowsMobile/Widget.cshtml WindowsMobile主页面文件
2. 修改视图引擎以支持Mobile
打开我们之前添加的WidgetViewEngine.cs,添加对Mobile支持
- 添加public StringDictionary Devices { get; set; },存储设备对应的目录
- 重载FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)方法
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Collections.Specialized; namespace Widgets { public class WidgetViewEngine : BuildManagerViewEngine { internal static readonly string ViewStartFileName = "_ViewStart"; public StringDictionary Devices { get; set; } public WidgetViewEngine() : this(null) { } public WidgetViewEngine(IViewPageActivator viewPageActivator) : base(viewPageActivator) { AreaViewLocationFormats = new[] { "~/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.cshtml" }; AreaMasterLocationFormats = new[] { "~/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.cshtml" }; AreaPartialViewLocationFormats = new[] { "~/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.cshtml" }; ViewLocationFormats = new[] { "~/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml" }; MasterLocationFormats = new[] { "~/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml" }; PartialViewLocationFormats = new[] { "~/{1}s/{0}/Widget.cshtml", "~/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml" }; // 初使化Mobile对应文件目录 Devices = new StringDictionary { {"IEMobile","WindowsMobile"}, {"Pocket IE","WindowsMobile"}, {"AppleMAC-Safari","iPhone"} }; FileExtensions = new[] { "cshtml" }; } protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath) { return new RazorView(controllerContext, partialPath, layoutPath: null, runViewStartPages: false, viewStartFileExtensions: FileExtensions, viewPageActivator: ViewPageActivator); } protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath) { var view = new RazorView(controllerContext, viewPath, layoutPath: masterPath, runViewStartPages: true, viewStartFileExtensions: FileExtensions, viewPageActivator: ViewPageActivator); return view; } public override ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache) { ViewEngineResult result = null; var request = controllerContext.HttpContext.Request; var isMobile = request.Browser.IsMobileDevice; if (isMobile && controllerContext.IsChildAction) { var device = request.Browser.Browser; result = base.FindPartialView( controllerContext, string.Format("{1}/Mobile/{0}", Devices[device], partialViewName), useCache); if ((result == null || result.View == null) && isMobile) result = base.FindPartialView( controllerContext, string.Format("{0}/Mobile", partialViewName), useCache); } if (result == null || result.View == null) result = base.FindPartialView(controllerContext, partialViewName, useCache); return result; } public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) { ViewEngineResult result = null; var request = controllerContext.HttpContext.Request; var isMobile = request.Browser.IsMobileDevice; if (isMobile) { var device = request.Browser.Browser; result = base.FindView( controllerContext, string.Format("Mobile/{0}/{1}", Devices[device], viewName), masterName, useCache); if ((result == null || result.View == null) && isMobile) result = base.FindView( controllerContext, string.Format("Mobile/{0}", viewName), masterName, useCache); } if (result == null || result.View == null) result = base.FindView(controllerContext, viewName, masterName, useCache); return result; } } }
3. 更改显示页面
/Mobile/Widget.cshtml
@model IEnumerable<Widgets.Models.Friend> @{ Layout = "~/widgets/_Layout.cshtml"; ViewBag.Title = "My friends"; } <div class="newsletter"> <ul> @foreach (var item in Model) { <li>@item.Name</li> } </ul> </div>
/Mobile/iPhone/Widget.cshtml
@model IEnumerable<Widgets.Models.Friend> @{ Layout = "~/widgets/_Layout.cshtml"; ViewBag.Title = "My friends"; } <div class="newsletter"> <ul> @foreach (var item in Model) { <li>@item.Name</li> } </ul> <span>来自iPhone手机客户端</span> </div>
/Mobile/WindowsMobile/Widget.cshtml
@model IEnumerable<Widgets.Models.Friend> @{ Layout = "~/widgets/_Layout.cshtml"; ViewBag.Title = "My friends"; } <div class="newsletter"> <ul> @foreach (var item in Model) { <li>@item.Name</li> } </ul> <span>来自windows mobile手机客户端</span> </div>
4. 使用Windows Phone 7 Emulator打开页面