Asp.NET MVC Widget开发 - Mobile支持
2011-03-02 15:49 Creative dream 阅读(2579) 评论(4) 编辑 收藏 举报在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支持
- Asp.NET MVC Widget - Html.Widget扩展方法
前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打开页面