1

请对我温柔一点,这是我潜伏多年后关于 StackOverflow 的第一个问题。

我有一个 MVC4 站点已经启动并运行。我正在向网站添加移动支持,使用标准 MVC 功能一切顺利:

如果没有“.Phone”版本的视图,我需要一些代码来允许框架使用 Layout.cshtml

示例 1

我有以下文件:

Views/Home/HasBoth.cshtml
Views/Home/HasBoth.Phone.cshtml

Views/Shared/Layout.cshtml
Views/Shared/Layout.Phone.cshtml

用桌面调用

  1. 致电 /Home/HasBoth
  2. 框架拿起不是移动设备
  3. 框架调用 Layout.cshtml
  4. 框架调用 HasBoth.cshtml

这很棒。

用手机打电话

  1. 致电 /Home/HasBoth
  2. 框架拿起移动设备
  3. 框架调用 Layout.Phone.cshtml
  4. 框架调用 HasBoth.Phone.cshtml

同样,这也很棒。

示例 2

我有以下文件:

Views/Home/HasNoPhone.cshtml

Views/Shared/Layout.cshtml
Views/Shared/Layout.Phone.cshtml

注意:没有 Views/Home/HasNoPhone.Phone.cshtml

用桌面调用

  1. 致电/首页/HasNoPhone
  2. 框架拿起不是移动设备
  3. 框架调用 Layout.cshtml
  4. 框架调用 HasNoPhone.cshtml

这很棒。

用手机打电话

  1. 致电/首页/HasNoPhone
  2. 框架拿起移动设备
  3. 这里的代码解决没有 HasNoPhone.Phone.cshtml 视图
  4. 框架调用Layout.cshtml
  5. 框架调用HasNoPhone.cshtml

以上是我想要实现的。

编辑

使用的解决方案

感谢 Zoka,我现在正在为其他希望做类似事情的人使用以下内容:

辅助方法:

/// <summary>
/// Looks to see if the view the exists.
/// </summary>
/// <param name="viewName">The view name.</param>
/// <param name="controllerContext">The controller context.</param>
/// <returns>True if the view exists.</returns>
public static bool ViewExists(string viewName, ControllerContext controllerContext)
{
  ViewEngineResult result = ViewEngines.Engines.FindView(controllerContext, viewName, null);
  return result.View != null;
}

_ViewStart.cshtml:

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

  // If a mobile viewing and no <view>.Phone.cshtml file is found set the override to desktop.                 
  // This will ensure _Layout.Phone.cshtml and yyy.Phone.cshtml partials are not called.                       
  string action = (string)ViewContext.Controller.ValueProvider.GetValue("action").RawValue;                    
  string controller = (string)ViewContext.RouteData.Values["Controller"];                                      
  string viewPhoneName = "~/Views/" + controller + "/" + action + ".Phone.cshtml";                             
  if (ViewContext.HttpContext.GetOverriddenBrowser().IsMobileDevice &&                                         
    MvcHelperAbove.ViewExists(viewPhoneName, ViewContext.Controller.ControllerContext) == false) 
  {                                                                                                            
    ViewContext.HttpContext.SetOverriddenBrowser(BrowserOverride.Desktop);                                     
  }                                                                                                            
}

_Layout.Phone.cshtml

...
@* Below is essential to allow css to work when going from Mobile to Desktop *@
<script>
  $(document).ready(function () {
    $.mobile.ajaxEnabled = false;
  });
</script>
...    

再次感谢大家。

4

2 回答 2

0

您可以使用现有的 jquery 移动包:

http://www.hanselman.com/blog/MakingASwitchableDesktopAndMobileSiteWithASPNETMVC4AndJQueryMobile.aspx

编辑:也许您可以使用页面安装程序并在容器中注册您的页面。这样你的控制器可以询问你的容器他应该返回哪个视图。

创建 WindsorViewPageActivator

于 2013-04-12T12:02:00.083 回答
0

据我了解您的问题,您需要了解是否存在某些观点。我使用放置在可从视图访问的任何类中的此类函数:

public static bool ViewExists(string _name, ControllerContext _controller_context)
{
    ViewEngineResult result = ViewEngines.Engines.FindView(_controller_context, _name, null);
    return (result.View != null);
}

然后把它放到_ViewStart.cshtml中:

string action = (string)ViewContext.Controller.ValueProvider.GetValue("action").RawValue;
string controller = (string)ViewContext.RouteData.Values["Controller"];
var viewPhoneName = "~/Views/" + controller + "/" + action + ".Phone.cshtml";
if (YourNamespaceAndClassForAboveHelper.ViewExists(viewPhoneName, ViewContext.Controller.ControllerContext)) {
    Layout = "~/Views/Shared/Layout.Phone.cshtml"
} else {
    Layout = "~/Views/Shared/Layout.cshtml"
}

最后在 Layout.cshml 中(分别在 Layout.Phone.cshtml 中),而不是调用RenderBody

string action = (string)ViewContext.Controller.ValueProvider.GetValue("action").RawValue;
string controller = (string)ViewContext.RouteData.Values["Controller"];
@RenderPage("~/Views/" + controller + "/" + action + ".cshtml"); @* .Phone.cshtml in Layout.Phone.cshtml *@
于 2013-04-12T11:34:51.697 回答