用ASP.NET MVC 4 和 jQuery Mobile制作一个可切换的桌面和移动站点

[原文发表地址]  Making a switchable Desktop and Mobile site with ASP.NET MVC 4 and jQuery Mobile

[原文发表时间] 2012-10-01 3:17 PM

我真的很乐于工作并思考于移动网站。开发一款很好用户体验的手机便携式超级计算机应用要比桌面应用更有成就感。其实,我这篇博客, 在 2006 年的移动设备上看起来不错,那时没有什么人使用移动设备,除了医生和我们这些博客上的技术人员。

我曾经在博文中谈及过一个好的移动网站的重要性,如就在今天,请为您的网站创建良好的移动体验。然而,有些人曾问我是否要发表一篇博文,关于如何使用 ASP.NET MVC 做一个桌面和移动相结合的网站,类似于我今年早些时候我在俄罗斯举行的关于移动网站的会谈一文中使用的那些示例。(这里是那些现有的 ASP.NET 移动演示视频)

在你启动 Visual Studio 2012 后,点击文件 |新建ASP.NET MVC 4 应用程序,你就能看到互联网应用程序模板和移动模板。第一个模板可以创建标准的桌面网站,虽然有可互动的设计元素,因此它适用于小屏幕。利用另一个模板可创建 jQuery Mobile应用程序,主要是应用于手机和平板电脑的移动应用程序。让我们做一个在两者之间切换的应用。

我们将为桌面在ASP.NET MVC中做一个小站点,做一些快速的 DB 访问,添加 jQuery Mobile和View Switcher(视图切换器)来回切换。我将使用来自Electric Plum的Electric Mobile Studio来模拟 iPhone。您可以获得 7 天试用或您可以获得Electric Plum手机模拟器的 WebMatrix 2 Lite 版本.

快速的 CRUD 示例

首先,一个DVD的model层:

 public class DVD
{
    public int ID { get; set; }
    public string Title { get; set; }
    public int Year { get; set; }
    public Rating rating { get; set; }
}

 public enum Rating{
    G, PG, PG13, R
}

接下来,生成索引、 创建、 编辑、 删除等。不幸的是不能- (我悲伤)为我的电影分级生成自动代码,所以我添加了EditorFor () 调用来创建和编辑,并且更新我的索引。

 <div class="editor-label">
    @Html.LabelFor(model => model.rating)
</div>
<div class="editor-field">
    @Html.EditorFor(model => model.rating)
    @Html.ValidationMessageFor(model => model.rating)
</div>

我本可以使用下拉列表,但我总是觉得它令人困惑。相反,我会创建一个 Rating.cshtml,它会形成一个下拉项。我可以在将来某个时刻,甚至在不使用下拉项的情况下对其进行更改。

Shared/EditorTemplates/Rating.cshtml旁白: 你们通常是怎样处理枚举的?我看到它有几种方法。我希望它变得更通用。下面是我做的评级编辑器模板。注意到nullable了吗 ?这用于创建和删除工作

 @model MyApp.Models.Rating?
@using MyApp.Models


 <select id="@ViewData.TemplateInfo.GetFullHtmlFieldId("")" name="@ViewData.TemplateInfo.GetFullHtmlFieldName("")">
 @foreach (int rating in Enum.GetValues(typeof(Rating))) {
        var name = Enum.GetName(typeof(Rating), rating);
        <option value="@name" selected="@(Model.HasValue ? (int)Model == rating : false)">@name</option>
    }
</select>

这是一个基本的桌面 CRUD 应用。

Editing a DVD

List of DVDs

使其移动化

如前所述,您可能已注意到,当你创建一个 ASP.NET MVC 应用程序的时候,您可以选择具有 jQuery 标准的"桌面"互联网应用程序的移动模板。但是,没有可切换式的模板。也就是说,一个适用于桌面的常规模板,却要切换到适用于移动设备的 jQuery Mobile模板 (或 KendoUI,或任何你乐于使用的模板) 。

iPhone in the Visual Studio browser menu使用 NuGet,安装 jQuery.Mobile.MVC 软件包。您可以右击References(引用),选择Manage NuGet Packages(管理NuGet 软件包),您还可以使用软件包管理器控制台输入:

 install-package jQuery.Mobile.MVC

此软件包会自动带来jQuery Mobile以及:

  • ViewSwitcher 的局部视图和辅助控制器,它促使我们手动切换桌面和移动
  • 一个基本的 _Layout.Mobile.cshtml ,支持样式表
  • 使用 ASP.NET 优化的(CSS 和 JS 捆绑程序) BundleMobileConfig.cs

注: JQuery Mobile的 ViewSwitcher 和这里的其他技术相比,没有什么特别的。令人高兴的是,您可以为任何其他流行的移动框架更改此程序包。

首先,我们在 Global.asax 中添加新的捆绑包:

 BundleConfig.RegisterBundles(BundleTable.Bundles);
BundleMobileConfig.RegisterBundles(BundleTable.Bundles); // <-- ADD THIS ONE

由于我安装了Electric Plum iPhone 模拟器,我就会从我的 Visual Studio 中的浏览器下拉列表中选择它,运行我的应用程序,然后导向/DVD。

在系统看来,我在移动设备上,它使用 _Layout.mobile.cshtml,而不是使用 _Layout.cshtml。

这并不真的好看。首先,我不喜欢默认样式。只需进入 _Layout.Mobile.cshtml,并将数据主题属性更改为任何值。我将主题a该为主题b。

Basic App in an iPhoneSame baisic app with a light background

然后,虽然我使用的是 _Layout.Mobile.cshtml,但我仍在使用当显示在移动布局上看起来会乱糟糟的桌面Index.cshtml。请记住我只有一个单个的 Index.cshtml。如果我有一个 Index.mobile.cshtml的话,当呈现在移动设备上时,系统将改用该页面。

我可以用更为简洁的标记创建一个 Index.Mobile.cshtml,将表构造为一个无序的列表,然后添加一些 jQuery Mobile特定属性,如:

 @model IEnumerable<MvcApplication2.Models.DVD>
@{
    ViewBag.Title = "My DVDs";
}
<ul data-role="listview" data-filter="true" >
 @foreach (var item in Model) {
    <li>
        <a href="@Url.Action("Details", new { item.ID })">
        <h2>@Html.DisplayFor(modelItem => item.Title)</h2>
        <p>@Html.DisplayFor(modelItem => item.Year) - @Html.DisplayFor(modelItem => item.rating)</p>
        </a>
    </li>
}
</ul>

请注意数据角色和非常基本的元素,如 <ul>、 <li>、 < h2 < 和 <p>。为了得到一些好的客户端搜索,我还添加了客户端数据筛选属性。点击刷新,它现在开始看起来像一个真正的移动网站了。

看到顶部的 ViewSwitcher 了吗?这是一个被称为 _ViewSwitcher.cshtml 的局部视图。

A lovely jQuery Mobile example list of DVDs

默认情况下,它会让你在桌面和移动之间来回切换,但仅限于在移动设备上。 为什么呢?请看下面第一行代码:

 @if (Request.Browser.IsMobileDevice && Request.HttpMethod == "GET")
{
    <div class="view-switcher ui-bar-a">
        @if (ViewContext.HttpContext.GetOverriddenBrowser().IsMobileDevice)
        {
            @: Displaying mobile view
            @Html.ActionLink("Desktop view", "SwitchView", "ViewSwitcher", new { mobile = false, returnUrl = Request.Url.PathAndQuery }, new { rel = "external" })
        }
         else
         {
            @: Displaying desktop view
            @Html.ActionLink("Mobile view", "SwitchView", "ViewSwitcher", new { mobile = true, returnUrl = Request.Url.PathAndQuery }, new { rel = "external" })
        }
    </div>
}

第一行代码检查是否是移动设备发出的请求。只是注释这些代码,您就可以用桌面游览器查看和调试移动布局,在没有欺骗用户代理的情况下。

到目前为止,我们一直在谈论"移动"和以"移动"作为文件名的一部分来创建文件,这一切都很神奇。原来我们有很多对这些东西的控制。也许我们不仅想要使用 Index.mobile.cshtml,而且或许还想使用Index.iPhone.cshtml 和 Index.WP7.cshtml。

添加如下代码行到您的 Global.asax中:

 DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("WP7") {
    ContextCondition = ctx => ctx.GetOverriddenUserAgent().Contains("Windows Phone OS")
});
DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("iPhone") {
    ContextCondition = ctx => ctx.GetOverriddenUserAgent().Contains("iPhone")
});

你可以插入到您自己的程序中来影响DisplayMode 集合("Mobile"是集合中的一个元素)。在这里我想提出两个更具体的Mobile,但您不必做些什么来更改 DisplayModes。DisplayMode 可以从右到左为RTL语言对齐,基于您对每个请求的评估 ContextCondition。

有很多选择,你可以根据你的喜好,灵活地处理事情,这样的灵活性你已经学会了。我将在今后的文章中展示一个使用 cache.manifest 的完全脱机 iPhone 站点的一个示例。