好的,我用自定义视图引擎继承了这段代码。它所做的只是覆盖FindView
,以便根据设备返回不同的视图。目前,iPad被检测为移动设备,因此显示移动视图。我的任务是将其更改为桌面视图。
有两个母版页X.master
和X.Mobile.master
。从代码中,您可以看到它手动将.Mobile
添加到移动设备的主页面名称中。我所做的只是为iPad设置isMobile
到false
。
问题是,即使它转到else语句,masterName
是X
(而不是X.Mobile
),但当使用iPad查看时,返回的视图将X.Mobile.Master
作为其主页面。因此,对于iPad来说,它最终会显示带有移动主页的桌面视图。桌面版和移动版都可以。这可能在哪里(以及如何)发生?
一种示例操作方法:
public ActionResult Index()
{
return View("Index", "X");
}
以下是视图引擎的简化版本:
class MobileViewEngine : FixedWebFormViewEngine
{
public override ViewEngineResult FindView(
ControllerContext controllerContext,
string viewName,
string masterName,
bool useCache
)
{
ViewEngineResult result;
bool isMobile =
controllerContext.HttpContext.Request.Browser.IsMobileDevice;
if (isiPad(controllerContext.HttpContext.Request))
{
isMobile = false;
}
if (isMobile)
{
masterName = masterName + ".Mobile";
string viewPathAndName = "M/" + viewName;
//Mobile view retrieved from cache
result = base.FindView(
controllerContext,
viewPathAndName,
masterName,
true
);
if (result == null || result.View == null)
{
//Mobile view retrieved, no cache
result = base.FindView(
controllerContext,
viewPathAndName,
masterName,
false
);
}
}
else
{
//desktop view retrieved
result = base.FindView(
controllerContext,
viewName,
masterName,
false
);
}
}
}
好的,所以在查看了ASP.NET MVC之后(感谢上帝的开源),我可以看到,当请求标记为mobile(controllerContext.HttpContext.Request.Browser.IsMobileDevice == true
)时,MVC默认会在尝试viewname.cshtml之前先尝试viewname.mobile.cshhtml(或.aspx)。母版页也是如此。
就我而言,因为确实有一个主页.mobile,所以它正在被渲染。至于视图,因为移动版本在一个单独的文件夹中,它没有被拾取,而是回落到正常的viewname.cshtml.
整个调查花了我一点时间,这促使我在博客中更详细地分享我的发现。