如何:向 ASP.NET Web 窗体 / MVC 应用程序添加移动页面

适用于

  • ASP.NET Web Forms版本 4.0
  • ASP.NET MVC 版本 3.0

摘要

本操作方法介绍了从 ASP.NET Web Forms/MVC 应用程序中为移动设备优化页面的各种方式,并建议在面向各种设备时要考虑的体系结构和设计问题。 本文档还介绍了为什么从 ASP.NET 2.0 到 3.5 的 ASP.NET 移动控件现已过时,并讨论了一些新式替代方法。

目录

  • 概述
  • 体系结构选项
  • 浏览器和设备检测
  • ASP.NET Web Forms应用程序如何显示特定于移动的页面
  • ASP.NET MVC 应用程序如何呈现特定于移动的页面
  • 其他资源

有关演示本白皮书针对 ASP.NET Web Forms 和 MVC 的技术的可下载代码示例,请参阅具有 ASP.NET 的移动应用 & 网站

概述

移动设备(智能手机、功能手机和平板电脑)作为访问 Web 的方式越来越受欢迎。 对于许多 Web 开发人员和面向 Web 的企业来说,这意味着为使用这些设备的访问者提供出色的浏览体验变得越来越重要。

早期版本的 ASP.NET 如何支持移动浏览器

ASP.NET 版本 2.0 到 3.5 包含在 移动控件 ASP.NETSystem.Web.Mobile.dll 程序集和 System.Web.UI.MobileControls 命名空间中移动设备的一组服务器控件。 程序集仍包含在 ASP.NET 4 中,但已弃用。 建议开发人员迁移到更现代的方法,如本文中所述的方法。

ASP.NET 移动控件之所以被标记为过时,是因为其设计针对的是 2005 年及更早版本常见的手机。 控件主要用于 (呈现 WML 或 cHTML 标记,而不是为该时代的 WAP 浏览器呈现常规 HTML) 。 但 WAP、WML 和 cHTML 不再与大多数项目相关,因为 HTML 现在已成为移动和桌面浏览器等无处不在的标记语言。

当今支持移动设备的挑战

尽管移动浏览器现在几乎普遍支持 HTML,但在创建出色的移动浏览体验时,你仍将面临许多挑战:

  • 屏幕大小 - 移动设备在形式上差异很大,其屏幕通常比桌面监视器小得多。 因此,可能需要为它们设计完全不同的页面布局。
  • 输入方法 – 某些设备具有键盘,有些设备具有触笔,其他设备使用触摸。 可能需要考虑多种导航机制和数据输入法。
  • 标准符合性 – 许多移动浏览器不支持最新的 HTML、CSS 或 JavaScript 标准。
  • 带宽 - 手机网络数据网络性能差异很大,一些最终用户收取的资费为兆字节。

没有一刀切的解决方案;应用程序的外观和行为必须根据访问它的设备而有所不同。 根据你想要的移动支持级别,对于 Web 开发人员来说,这比桌面“浏览器大战”要大。

首次获得移动浏览器支持的开发人员通常最初认为支持最新且最复杂的智能手机 ((例如,Windows Phone 7、iPhone 或 Android) )非常重要,这也许是因为开发人员通常亲自拥有此类设备。 然而,更便宜的手机仍然非常受欢迎,其所有者确实使用它们来浏览网络,尤其是在手机比宽带连接更容易获取的国家和地区。 你的企业需要通过考虑其可能的客户来决定要支持哪些设备范围。 如果你正在为豪华健康水疗中心制作一个在线小册子,你可能会做出商业决定,只针对高级智能手机,而如果你正在为电影院创建票务预订系统,你可能需要考虑功能手机功能较弱的游客。

体系结构选项

在我们了解 ASP.NET Web Forms或 MVC 的特定技术详细信息之前,请注意,Web 开发人员通常有三main支持移动浏览器的可能选项:

  1. 不执行任何操作 - 只需创建面向桌面的标准 Web 应用程序,并依靠移动浏览器来接受呈现它。

    • 优点:这是实现和维护的最便宜的选项 - 无需额外工作

    • 缺点:提供最差的最终用户体验:

      • 最新的智能手机可以像桌面浏览器一样呈现你的 HTML,但用户仍将被迫水平和垂直缩放,以在小屏幕上使用你的内容。 这远非最佳状态。
      • 旧设备和功能手机可能无法以令人满意的方式呈现标记。
      • 即使在最新的平板电脑设备上, (其屏幕可以像笔记本电脑屏幕) 一样大,不同的交互规则也适用。 基于触摸的输入最适合较大的按钮和链接分开,并且无法将鼠标光标悬停在弹出菜单上。
  2. 解决客户端上的问题 仔细使用 CSS 和 渐进式增强 功能,可以创建适合运行它们的浏览器的标记、样式和脚本。 例如,使用 CSS 3 媒体查询,可以在屏幕比所选阈值窄的设备上创建多列布局,该布局转换为单列布局。

    • 优点:针对使用中的特定设备优化呈现,甚至针对未来未知设备,根据它们具有的任何屏幕和输入特征优化呈现
    • 优点:轻松跨所有设备类型共享服务器端逻辑 - 最少的代码重复或工作量
    • 缺点:移动设备与桌面设备大不相同,因此你可能确实希望移动页面与桌面页面完全不同,显示不同的信息。 此类变体可能效率低下,或者无法仅通过 CSS 以可靠的方式实现,特别是考虑到旧设备解释 CSS 规则的方式如何不一致。 CSS 3 属性尤其如此。
    • 缺点:不支持不同设备的不同服务器端逻辑和工作流。 例如,不能仅通过 CSS 为移动用户实现简化的购物车结帐工作流。
    • 缺点:带宽使用效率低下。 服务器可能必须传输适用于所有可能设备的标记和样式,即使目标设备将仅使用该信息的子集。
  3. 解决服务器上的问题 如果服务器知道哪个设备正在访问它,或者至少知道该设备的特征,例如其屏幕大小和输入法,以及它是否为移动设备,则它可以运行不同的逻辑并输出不同的 HTML 标记。

    • 优势: 最大的灵活性。 对于移动设备,可以改变服务器端逻辑或针对所需的特定于设备的布局优化标记没有限制。
    • 优势: 高效使用带宽。 只需传输目标设备将使用的标记和样式信息。
    • 缺点:有时会强制重复工作或代码 (例如,使你创建Web Forms页面或 MVC 视图) 相似但略有不同的副本。 在可能的情况下,你将将常见逻辑分解为基础层或服务,但仍可能需要复制 UI 代码或标记的某些部分,然后并行维护。
    • 缺点: 设备检测并非易事。 它需要已知设备类型及其特征的列表或数据库 (它们可能并不总是完全最新的) ,并且不能保证准确匹配每个传入的请求。 本文档稍后介绍一些选项及其缺陷。

为了获得最佳结果,大多数开发人员发现他们需要组合选项 (2) 和 (3) 。 使用 CSS 甚至 JavaScript 在客户端上最好适应轻微的样式差异,而数据、工作流或标记方面的重大差异在服务器端代码中最有效地实现。

本文重点介绍服务器端技术

由于 ASP.NET Web Forms和 MVC 都主要是服务器端技术,本白皮书将重点介绍服务器端技术,以便为移动浏览器生成不同的标记和逻辑。 当然,还可以将其与任何客户端技术相结合, (例如 CSS 3 媒体查询、渐进式增强 JavaScript) ,但这与其说是 ASP.NET 开发,不如说是 Web 设计的问题。

浏览器和设备检测

支持移动设备的所有服务器端技术的关键先决条件是了解访问者使用的设备。 事实上,比了解该设备的制造商和型号更好的是了解设备 的特征 。 特征可能包括:

  • 是移动设备吗?
  • 输入法 (鼠标/键盘、触摸、键盘、游戏杆...)
  • 屏幕大小 (物理和像素)
  • 支持的媒体和数据格式
  • 等。

根据特征做出决策比基于型号更好,因为这样你就能够更好地处理未来的设备。

使用 ASP。NET 的内置浏览器检测支持

ASP.NET Web Forms和 MVC 开发人员可以通过检查 Request.Browser 对象的属性,立即发现访问浏览器的重要特征。 有关示例,请参阅

  • Request.Browser.IsMobileDevice
  • Request.Browser.MobileDeviceManufacturer、Request.Browser.MobileDeviceModel
  • Request.Browser.ScreenPixelsWidth
  • Request.Browser.SupportsXmlHttp
  • ...和许多其他工具

在后台,ASP.NET 平台将传入 的用户代理 (UA) HTTP 标头与一组浏览器定义 XML 文件中的正则表达式进行匹配。 默认情况下,平台包含许多常见移动设备的定义,你可以为要识别的其他设备添加自定义浏览器定义文件。 有关详细信息,请参阅 MSDN 页 ASP.NET Web 服务器控件和浏览器功能

通过 51Degrees.mobi Foundation 使用 WURFL 设备数据库

当 ASP。NET 的内置浏览器检测支持对于许多应用程序来说已经足够了,main两种情况可能不够:

  • 你希望识别最新的设备 (,而无需手动为它们创建浏览器定义文件) 。 请注意,.NET 4 的浏览器定义文件不够最新,无法识别Windows Phone 7、Android 手机、Opera Mobile 浏览器或 Apple iPad。
  • 需要有关设备功能的详细信息。 你可能需要了解设备的输入法 (例如触摸与键盘) ,或者浏览器支持的音频格式。 此信息在标准浏览器定义文件中不可用。

无线通用资源文件 (WURFL) 项目维护有关当前正在使用的移动设备的更新和详细信息。

对于 .NET 开发人员来说,这个好消息是 ASP。NET 的浏览器检测功能是可扩展的,因此可以对其进行增强以解决这些问题。 例如,可以将 开放源代码 51Degrees.mobi Foundation 库添加到项目中。 它是 ASP.NET IHttpModule 或浏览器功能提供程序, (Web Forms和 MVC 应用程序) 都可用,可直接读取 WURFL 数据并将其挂钩到 ASP。NET 的内置浏览器检测机制。 安装模块后, Request.Browser 将突然包含更准确和详细的信息:它将正确识别前面提到的许多设备,并列出其功能 (包括输入法) 等其他功能。 有关更多详细信息,请参阅项目的文档。

Web Forms应用程序如何显示特定于移动的页面

默认情况下,下面是全新Web Forms应用程序在常见移动设备上的显示方式:

Windows Phone 7 和 Opera Mobile 上显示的两个Web Forms应用程序的屏幕截图。

显然,这两种布局看起来都不十分适合移动设备 - 此页面专为大型横向显示器设计,而不是面向纵向的小型屏幕。 那么,你能做些什么呢?

如本文前面所述,有多种方法可针对移动设备定制页面。 某些技术基于服务器,其他技术在客户端上运行。

创建特定于移动的母版页

根据你的要求,你可能能够对所有访问者使用相同的Web Forms,但有两个单独的母版页:一个用于桌面访问者,另一个用于移动访问者。 这使你可以灵活地更改 CSS 样式表或顶级 HTML 标记以适应移动设备,而无需强制复制任何页面逻辑。

这很容易做到。 例如,可以将 PreInit 处理程序(如下所示)添加到 Web 窗体:

protected void Page_PreInit(object sender, EventArgs e)
{
    if (Request.Browser.IsMobileDevice)
        MasterPageFile = "~/Mobile.Master";
}

现在,在应用程序的顶级文件夹中创建一个名为 Mobile.Master 的母版页,并在检测到移动设备时使用该母版页。 如有必要,移动母版页可以引用特定于移动设备的 CSS 样式表。 桌面访问者仍将看到你的默认母版页,而不是移动版页。

创建特定于移动的独立Web Forms

为了获得最大的灵活性,可以进一步操作,而不仅仅是为不同的设备类型提供单独的母版页。 你可以实现两组完全独立的Web Forms页面 - 一组用于桌面浏览器,另一组用于移动设备。 如果要向移动访问者呈现截然不同的信息或工作流,则此方法效果最佳。 本部分的其余部分详细介绍了此方法。

假设已有专为桌面浏览器设计的Web Forms应用程序,最简单的方法是在项目中创建名为“Mobile”的子文件夹,并在其中生成移动页面。 可以使用用于任何其他Web Forms应用程序的所有相同技术,构造整个子网站及其自己的母版页、样式表和页面。 不一定需要为桌面网站 中的每个 页面生成移动等效项;可以选择对移动访问者有意义的功能子集。

移动页面可以根据需要与常规页面共享常见静态资源 (,例如图像、JavaScript 或 CSS 文件) 。 由于“移动”文件夹在 IIS 中托管时不会标记为单独的应用程序 (它只是) Web Forms页的简单子文件夹,因此它还将与桌面页面共享所有相同的配置、会话数据和其他基础结构。

注意

由于此方法通常涉及一些代码重复, (移动页面可能会与桌面页面) 共享一些相似之处,因此请务必将任何常见的业务逻辑或数据访问代码分解为共享的基础层或服务。 否则,创建和维护应用程序的工作量将增加一倍。

将移动访问者重定向到移动页面

通常,仅在其浏览会话 (的第一个 请求上将移动访问者重定向到移动页面,而不是在其会话) 中的每个请求上重定向移动页面很方便,因为:

  • 然后,你可以轻松允许移动访问者访问你的桌面页面(如果他们愿意)只需在母版页上放置一个指向“桌面版本”的链接。 不会将访问者重定向回移动页面,因为它不再是其会话中的第一个请求。
  • 它避免了干扰网站桌面和移动部件之间共享的任何动态资源请求的风险, (例如,如果你有一个通用的 Web 表单,该网站的桌面和移动部件都显示在 IFRAME 中,或者某些 Ajax 处理程序)

为此,可以将重定向逻辑置于 Session_Start 方法中。 例如,将以下方法添加到 Global.asax.cs 文件:

void Session_Start(object sender, EventArgs e)
{
    // Redirect mobile users to the mobile home page
    HttpRequest httpRequest = HttpContext.Current.Request;
    if (httpRequest.Browser.IsMobileDevice)
    {
        string path = httpRequest.Url.PathAndQuery;
        bool isOnMobilePage = path.StartsWith("/Mobile/", 
                               StringComparison.OrdinalIgnoreCase);
        if (!isOnMobilePage)
        {
            string redirectTo = "~/Mobile/";

            // Could also add special logic to redirect from certain 
            // recognized pages to the mobile equivalents of those 
            // pages (where they exist). For example,
            // if (HttpContext.Current.Handler is UserRegistration)
            //     redirectTo = "~/Mobile/Register.aspx";

            HttpContext.Current.Response.Redirect(redirectTo);
        }
    }
}

配置 Forms 身份验证以遵循你的移动页面

请注意,Forms 身份验证会做出一些假设,即在身份验证过程期间和之后可以重定向访问者的位置:

  • 当用户需要进行身份验证时,Forms 身份验证会将他们重定向到桌面登录页,无论他们是桌面用户还是移动用户 (,因为它只有 一个 登录 URL 的概念) 。 假设你想要以不同的方式设置移动登录页的样式,则需要增强桌面登录页,以便它将移动用户重定向到单独的移动登录页。 例如,将以下代码添加到 桌面 登录页代码隐藏:

    public partial class Login : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // Ensure that if Forms Authentication forces a mobile user 
            // to log in, we display the mobile login page
            string returnUrl = Request.QueryString["ReturnUrl"];
            if (!String.IsNullOrEmpty(returnUrl) && returnUrl.StartsWith("/Mobile/",
                                                    StringComparison.OrdinalIgnoreCase)) 
            {
                Response.Redirect("~/Mobile/Account/Login.aspx?ReturnUrl=" 
                                  + HttpUtility.UrlEncode(returnUrl));
            }
    
            RegisterHyperLink.NavigateUrl = "Register.aspx?ReturnUrl=" 
                                            + HttpUtility.UrlEncode(returnUrl);
        }
    }
    
  • 用户成功登录后,表单身份验证默认会将其重定向到桌面主页 (,因为它只有 一个 默认页面的概念) 。 需要增强移动登录页,使其在成功登录后重定向到移动主页。 例如,将以下代码添加到 移动 登录页代码隐藏:

    public partial class Login : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // Ensure that after logging in, mobile users stay on mobile pages
            string returnUrl = Request.QueryString["ReturnUrl"];
            if (String.IsNullOrEmpty(returnUrl))
            {
                returnUrl = "~/Mobile/";
            }
            LoginUser.DestinationPageUrl = returnUrl;
    
            // (the following line is already present by default)
            RegisterHyperLink.NavigateUrl = "Register.aspx?ReturnUrl=" 
                                            + HttpUtility.UrlEncode(returnUrl);
        }
    }
    

    此代码假定页面具有名为 LoginUser 的 Login 服务器控件,如默认项目模板中所示。

使用输出缓存

如果使用输出缓存,请注意,默认情况下,桌面用户可能会访问特定的 URL (导致其输出被缓存) ,然后是一个移动用户,后者随后接收缓存的桌面输出。 无论只是按设备类型更改母版页,还是为每个设备类型实现完全独立的Web Forms,此警告都适用。

若要避免此问题,可以指示 ASP.NET 根据访问者是否使用移动设备来改变缓存条目。 将 VaryByCustom 参数添加到页面的 OutputCache 声明中,如下所示:

<%@ OutputCache VaryByParam="*" Duration="60" VaryByCustom="isMobileDevice" %>

接下来,通过将以下方法重写添加到 Global.asax.cs 文件,将 isMobileDevice 定义为自定义缓存参数:

public override string GetVaryByCustomString(HttpContext context, string custom)
{
    if (string.Equals(custom, "isMobileDevice", StringComparison.OrdinalIgnoreCase))
        return context.Request.Browser.IsMobileDevice.ToString();

    return base.GetVaryByCustomString(context, custom);
}

这将确保页面的移动访问者不会收到桌面访问者之前放入缓存的输出。

一个工作示例

若要查看这些方法的运行情况,请下载 此白皮书的代码示例。 Web Forms示例应用程序自动将移动用户重定向到名为 Mobile 的子文件夹中的一组特定于移动的页面。 这些页面的标记和样式针对移动浏览器进行优化,如以下屏幕截图所示:

Windows Phone 7 和 Opera Mobile 上显示的两个移动Web Forms应用程序的屏幕截图。

有关优化移动浏览器的标记和 CSS 的更多提示,请参阅本文档后面的“为移动浏览器设置移动页面样式”部分。

ASP.NET MVC 应用程序如何呈现特定于移动的页面

由于模型-视图-控制器模式将控制器) 中的应用程序逻辑 (与视图) 中的呈现逻辑 (分离,因此可以从以下任一方法来处理服务器端代码中的移动支持:

  1. 对桌面和移动浏览器使用相同的控制器和视图,但根据设备类型使用不同的 Razor 布局呈现视图 如果你在所有设备上显示相同的数据,但只想提供不同的 CSS 样式表或更改一些移动设备的顶级 HTML 元素,则此选项效果最佳。
  2. 对桌面浏览器和移动浏览器使用相同的控制器,但根据设备类型呈现不同的视图。 如果你显示大致相同的数据并为最终用户提供相同的工作流,但想要呈现非常不同的 HTML 标记以适应正在使用的设备,则此选项效果最佳。
  3. 为桌面和移动浏览器创建单独的区域,为每个区域实现独立的控制器和视图 如果你显示的屏幕非常不同,包含不同的信息并引导用户完成针对其设备类型进行优化的不同工作流,则此选项效果最佳。 这可能意味着代码的一些重复,但你可以通过将通用逻辑分解到基础层或服务中来最大程度地减少这种重复。

如果想要采用 第一 个选项,并且仅根据设备类型更改 Razor 布局,则非常简单。 只需修改 _ViewStart.cshtml 文件,如下所示:

@{
    Layout = Request.Browser.IsMobileDevice ? "~/Views/Shared/_LayoutMobile.cshtml"
                                            : "~/Views/Shared/_Layout.cshtml";
}

现在,可以使用页面结构和针对移动设备优化的 CSS 规则创建名为 _LayoutMobile.cshtml 的特定于移动的布局。

如果要根据访问者的设备类型采用 第二 个选项来呈现完全不同的视图,请参阅 Scott Hanselman 的博客文章

本文的其余部分重点介绍 第三 个选项-为移动设备创建单独的控制器 视图,以便你可以准确控制为移动访问者提供的功能子集。

在 ASP.NET MVC 应用程序中设置移动区域

可以按正常方式将名为“移动”的区域添加到现有 ASP.NET MVC 应用程序:右键单击解决方案资源管理器中的项目名称,然后选择“添加区域”。 然后,可以像添加 ASP.NET MVC 应用程序内的任何其他区域一样添加控制器和视图。 例如,向移动区域添加一个名为 HomeController 的新控制器,充当移动访问者的主页。

确保 URL/Mobile 到达移动主页

如果希望 URL /Mobile 访问移动区域内 HomeController 上的 Index 操作,则需要对路由配置进行两个小更改。 首先,更新 MobileAreaRegistration 类,使 HomeController 成为移动区域中的默认控制器,如以下代码所示:

public override void RegisterArea(AreaRegistrationContext context)
{
    // By default there is no "controller" parameter in the following line. 
    // Add one referencing "Home" as shown.
    context.MapRoute(
        "Mobile_default",
        "Mobile/{controller}/{action}/{id}",
        new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}

这意味着移动主页现在将位于 /Mobile,而不是 /Mobile/Home,因为“Home”现在是移动页面的隐式默认控制器名称。

接下来,请注意,通过将第二个 HomeController 添加到应用程序 (即移动版,除了现有桌面一个) ,你还将破坏常规桌面主页。 它将失败,并出现错误“找到与名为'Home'的控制器匹配的多个类型”。 若要解决此问题,请更新 Global.asax.cs) 中的顶级路由配置 (,以指定在存在歧义时桌面 HomeController 应优先处理:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "Default",
        "{controller}/{action}/{id}",
        new { controller = "Home", action = "Index", id = UrlParameter.Optional },
        // Add the namespace of your desktop controllers here
        new[] { "YourApplication.Controllers" } 
    );
}

现在,错误将消失,http:// yoursite/ 的 URL 将到达桌面主页,http:// yoursite/mobile/ 将到达移动主页。

将移动访问者重定向到移动区域

ASP.NET MVC 中有许多不同的扩展点,因此有多种可能的方法可以注入重定向逻辑。 一个整洁的选项是创建筛选器属性 [RedirectMobileDevicesToMobileArea],该属性在满足以下条件时执行重定向:

  1. 这是用户会话 (的第一个请求,即 Session.IsNewSession 等于 true)
  2. 请求来自移动浏览器 (即 Request.Browser.IsMobileDevice 等于 true)
  3. 用户尚未请求移动区域中的资源 (即 URL 的路径 部分不以 /Mobile 开头)

此白皮书随附的可下载示例包括此逻辑的实现。 它作为授权筛选器实现,派生自 AuthorizeAttribute,这意味着即使使用输出缓存 (也可以正常工作,否则,如果桌面访问者首先访问某个 URL,桌面输出可能会被缓存,然后提供给后续移动访问者) 。

由于它是一个筛选器,因此可以选择将其应用于特定控制器和操作,例如

public class HomeController : Controller
{
    [RedirectMobileDevicesToMobileArea] // Applies just to this action
    public ActionResult Index()
    {
        // ...
    }
}

… 或者,可以将它作为 Global.asax.cs 文件中的 MVC 3 全局筛选器 应用于所有控制器和操作:

protected void Application_Start()
{
    // (rest of method unchanged)

    // Using "order" value 1 means it will run after unordered filters
    // associated with specific controllers or actions, so the redirection 
    // location can be overridden for specific actions
    GlobalFilters.Filters.Add(new RedirectMobileDevicesToMobileAreaAttribute(), 1);
}

可下载的示例还演示了如何创建此属性的子类,这些子类重定向到移动区域中的特定位置。 这意味着,例如,你可以:

  • 注册一个全局筛选器,如上所示,该筛选器默认将移动访问者发送到移动主页。
  • 此外,将特殊的 [RedirectMobileDevicesToMobileProductPage] 筛选器应用于“查看产品”操作,该操作将移动访问者带到他们请求的任何产品页面的移动版本。
  • 此外,将筛选器的其他特殊子类应用于特定操作,将移动访问者重定向到等效的移动页面

配置 Forms 身份验证以遵循你的移动页面

如果使用表单身份验证,应注意,当用户需要登录时,它会自动将用户重定向到单个特定的“登录”URL,该 URL 默认为 /Account/LogOn。 这意味着移动用户可能会被重定向到桌面“登录”操作。

若要避免此问题,请将逻辑添加到桌面“登录”操作,以便它将移动用户再次重定向到移动“登录”操作。 如果使用默认 ASP.NET MVC 应用程序模板,请更新 AccountController 的 LogOn 操作,如下所示:

public ActionResult LogOn()
{
    string returnUrl = Request.QueryString["ReturnUrl"];
    if ((returnUrl != null) && returnUrl.StartsWith("/Mobile/", 
                               StringComparison.OrdinalIgnoreCase)) 
    {
        return RedirectToAction("LogOn", "Account", 
                                new { Area = "Mobile", ReturnUrl = returnUrl });
    }
    return View();
}

… 然后在移动区域中名为 AccountController 的控制器上实施合适的特定于移动的“登录”操作。

使用输出缓存

如果使用 [OutputCache] 筛选器,则必须强制缓存条目因设备类型而异。 例如,编写:

[OutputCache(Duration = 60, VaryByParam = "*", VaryByCustom = "isMobileDevice")]

然后,将以下方法添加到 Global.asax.cs 文件:

public override string GetVaryByCustomString(HttpContext context, string custom)
{
    if (string.Equals(custom, "isMobileDevice", StringComparison.OrdinalIgnoreCase))
        return context.Request.Browser.IsMobileDevice.ToString();

    return base.GetVaryByCustomString(context, custom);
}

这将确保页面的移动访问者不会收到桌面访问者之前放入缓存的输出。

一个工作示例

若要查看这些方法的运行情况,请下载 此白皮书的代码关联示例。 该示例包括一个 ASP.NET MVC 3 (候选发布) 应用程序,该应用程序已增强,以便使用上述方法支持移动设备。

进一步的指导和建议

以下讨论适用于使用本文档中所述技术的Web Forms和 MVC 开发人员。

使用 51Degrees.mobi Foundation 增强重定向逻辑

本文档中显示的重定向逻辑对于应用程序而言可能完全足够,但如果需要禁用会话,或者使用拒绝 cookie 的移动浏览器, (这些浏览器无法) 会话,则它将无法知道给定的请求是否是来自该访问者的第一个请求。

你已经了解了 开放源代码 51Degrees.mobi Foundation 如何提高 ASP 的准确性。NET 的浏览器检测。 它还具有将移动访问者重定向到 Web.config 中配置的特定位置的内置功能。它可以在不依赖于 ASP.NET 会话 (的情况下工作,因此 cookie 通过存储访问者的 HTTP 标头和 IP 地址的哈希临时日志来) ,因此它知道每个请求是否是给定 vistor 中的第一个请求。

添加到 web.config 文件的 fiftyOne 部分的以下元素会将第一个请求从检测到的移动设备重定向到页面 ~/Mobile/Default.aspx。 无论设备类型如何,都不会重定向对 Mobile 文件夹下页面的任何请求。 如果移动设备处于非活动状态 20 分钟或更长时间,设备将被遗忘,并且出于重定向目的,后续请求将被视为新请求。

<redirect firstRequestOnly="true"
          mobileHomePageUrl="~/Mobile/Default.aspx"
          timeout="20"
          devicesFile="~/App_Data/Devices.dat"
          mobilePagesRegex="/Mobile/" />

有关详细信息,请参阅 51degrees.mobi Foundation 文档

注意

可以在 ASP.NET MVC 应用程序上使用 51Degrees.mobi Foundation 的重定向功能,但需要根据纯 URL 定义重定向配置,而不是在路由参数方面或通过将 MVC 筛选器置于操作上来定义重定向配置。 这是因为在编写) 51Degrees.mobi Foundation 时 (无法识别筛选器或路由。

禁用转码器和代理服务器

移动网络运营商在移动 Internet 方面有两个广泛的目标:

  1. 提供尽可能多的相关内容
  2. 最大化可以共享有限无线电网络带宽的客户数量

由于大多数网页专为大型桌面大小的屏幕和快速固定线路宽带连接而设计,许多操作员使用动态更改 Web 内容的 转码器代理服务器 。 它们可能会修改 HTML 标记或 CSS 以适应较小的屏幕 (尤其是对于缺乏处理复杂布局) 处理能力的“功能手机”,并且可能会重新压缩图像 (显著降低其质量) 以提高页面传送速度。

但是,如果您已努力生成站点的移动优化版本,您可能不希望网络运营商进一步干扰它。 可以将以下行添加到任何 ASP.NET Web 窗体中的 Page_Load 事件:

Response.Cache.SetNoTransforms();

或者,对于 ASP.NET MVC 控制器,可以添加以下方法重写,使其应用于该控制器上的所有操作:

protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
    filterContext.HttpContext.Response.Cache.SetNoTransforms();
}

生成的 HTTP 消息通知 W3C 兼容的转码器和代理不要更改内容。 当然,不能保证移动网络运营商会尊重此消息。

为移动浏览器设置移动页面样式

本文档无法非常详细地描述哪些类型的 HTML 标记正常工作,或者哪些 Web 设计技术在特定设备上最大化可用性。 由你来决定找到一个足够简单的布局,针对移动大小的屏幕进行优化,而无需使用不可靠的 HTML 或 CSS 定位技巧。 但是,值得一提的一个重要技术是 视区元标记

某些现代移动浏览器会努力显示用于桌面监视器的网页,在虚拟画布上呈现页面,也称为“视区” (例如,在 iPhone 上,虚拟视区宽度为 980 像素,在 Opera Mobile 上默认为 850 像素宽) ,然后缩小结果以适应屏幕的物理像素。 然后,用户可以放大和平移该视区。 这样做的优点是,它允许浏览器在其预期布局中显示页面,但它也有一个缺点,即它强制缩放和平移,这对用户来说很不方便。 如果针对移动设备进行设计,最好设计窄屏,以便无需缩放或水平滚动。

通过非标准视区元标记告知移动浏览器视区应有多宽的 种方法。 例如,如果将以下内容添加到页面的“HEAD”部分,

<meta name="viewport" content="width=480">

… 然后,支持智能手机的浏览器将在 480 像素宽的虚拟画布上布局页面。 这意味着,如果 HTML 元素以百分比形式定义其宽度,则会根据此 480 像素宽度(而不是默认视区宽度)解释百分比。 因此,用户不太可能需要水平缩放和平移,从而显著改善移动浏览体验。

如果希望视区宽度与设备的物理像素匹配,可以指定以下内容:

<meta name="viewport" content="width=device-width">

要使此功能正常工作,不得显式强制元素超过该宽度 (例如,使用 width 属性或 CSS 属性) ,否则浏览器将被迫使用更大的视区,不管怎样。 另请参阅: 有关非标准视区标记的更多详细信息

大多数现代智能手机支持 双方向:它们可以在纵向或横向模式下举行。 因此,请务必不要假设屏幕宽度(以像素为单位)。 甚至不要假设屏幕宽度是固定的,因为用户可以在你的页面上重新定位他们的设备。

较旧的 Windows Mobile 和 Blackberry 设备也可能接受页眉中的以下元标记,以通知它们内容已针对移动设备进行了优化,因此不应进行转换。

<meta name="MobileOptimized" content="width" />
<meta name="HandheldFriendly" content="true" />

其他资源

有关可用于测试移动 ASP.NET Web 应用程序的移动设备仿真器和模拟器的列表,请参阅 模拟常用移动设备进行测试页。

信用

  • 主要作者:史蒂文·桑德森
  • 审阅者/其他内容作者:James Rosewell、Mikael Söderström、Scott Hanselman、Scott Hunter