4

我一直在使用这篇文章开发我网站主页的移动版本:http ://www.hanselman.com/blog/MakingASwitchableDesktopAndMobileSiteWithASPNETMVC4AndJQueryMobile.aspx作为指南。

我有两个控制器: HomeController 和 EventController

HomeController 有一个 Index 视图,EventController 有一个 Detail 视图

我设法创建了一个正确使用 _Layout.mobile.cshtml 的 Index.mobile.cshtml 视图。现在,当用户在她的手机上访问 mysite.com/Home/Index 时,它会正确显示移动版本。

现在,我预计如果同一用户访问 mysite.com/Event/Detail/123,将显示默认的“桌面”视图(我没有Detail.mobile.cshtml 视图)。

问题是确实调用了 Detail.cshtml 视图,但它尝试使用 _Layout.mobile.cshtml 布局,使页面看起来很糟糕。

有没有办法实现这一点(只是为那些我没有在移动设备上实现的桌面布局渲染桌面视图)?

谢谢!

4

4 回答 4

3

将以下行添加到 _ViewStart.cshtml 文件的末尾:

DisplayModeProvider.Instance.RequireConsistentDisplayMode = true;

这将阻止应用程序在您的移动布局中显示非移动视图,反之亦然。

于 2014-04-22T12:51:00.460 回答
1

请注意,您似乎可以通过将这行代码放在控制器操作中来基于每个视图解决此问题。

HttpContext.SetOverriddenBrowser(BrowserOverride.Desktop);

但是,我真正想要的是一个解决方案,它基本上说如果当前视图的名称/路径中没有 .Mobile,请不要将布局切换到 .Mobile 版本

于 2013-11-08T14:32:42.430 回答
1

我以前没有使用过这个NUGET 包,但请注意它提到:

默认情况下,它允许您在桌面和移动设备之间来回切换,但仅限于移动设备。为什么?查看第一行代码:代码首先检查移动设备,如下所示:

@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>
}

根据 MSDN :

一般来说,我们建议您避免在视图中包含逻辑。它可能很难发现,甚至更难测试。相反,视图中的逻辑应该移动到视图模型或控制器操作中。

问题解决:根据您的需要更改默认逻辑,也许通过跟踪视图(断点也适用于视图)来满足您的目的。

您需要结合 MVC 和命名包来了解这个 MSDN 主题。了解 Action 中发生的事情可以解决您的问题。

于 2013-11-10T08:48:02.083 回答
0

最简单的解决方案是使用 _Layout.cshtml 显式覆盖 Detail.cshtml 上的布局:

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

如果您想要更通用的解决方案,您可以尝试以下方法:

创建自定义显示模式:

public class MobileDisplayMode : IDisplayMode
{
    private bool _mobileViewWasUsed = false;

    public override DisplayInfo GetDisplayInfo(HttpContextBase httpContext, string virtualPath, Func<string, bool> virtualPathExists)
    {
        string filePath = this.TransformPath(virtualPath, this._suffix);
        if (filePath != null && virtualPathExists(filePath))
        {
            if (!_mobileViewWasUsed)
            {
                if (virtualPath.IndexOf("layout", StringComparison.InvariantCultureIgnoreCase) != -1)
                    return (DisplayInfo) null;

                _mobileViewWasUsed = true;
            }
            return new DisplayInfo(filePath, (IDisplayMode) this);
        }
        else
            return (DisplayInfo) null;
    }
}

在 global.asax 中添加它:

DisplayModeProvider.Instance.Modes.Insert(0, new MobileDisplayMode("mobile"));

不幸的是,当它基于一些未经批准的假设(如根据请求创建 DisplayMode 等)时,没有机会对其进行测试。无论如何,如果您有兴趣并有机会对其进行测试,那就太好了。

于 2013-11-14T18:42:35.313 回答