受欢迎的博客标签

NopCommerce 3.4中移动端访问抛弃响应式布局

Published
在Nop3.4中,他抛弃了原来的xxx.Mobile.cshtml的这种写法,而是采用了响应式布局,并且把规则也给改了,你在后台配置不启用响应式布局,在前台你仍然不能写xxx.Mobile.cshtml这样。查了一天的原因,终于查出来了。

看完这个,估计你也会被误导,认为MVC已经自己支持了.Mobile.cshtml这种写法。觉得他肯定是哪里把那个设置给禁用了,反正我就是顺着这种思路找了一个早上无果。最后我断点跟踪他Return View()的方法,发现,他根本没有用MVC自己的那个方法,而是自己重写了一套。

在Return View的时候,他请求到Nop.Web.Framework这个项目下面的Themes文件夹里面的ThemeableVirtualPathProviderViewEngine文件中,在这个文件中有这样两个方法:FindView 和FindPartialView,在这里,他在3.4版本中的做法是直接把Controller丢到FindThemeableView方法中去执行了,然后细看FindThemeableView方法,你会发现,在它这里面,他会用Controller和Aciton组合起来,最后拼成一个Nop中Cshtml的路径。

比如像这样:newLocations.Insert(0, "~/Administration/Views/{1}/{0}.cshtml"); //不是这句代码,不要在这里动手脚。。

所以,只要FindView 和FindPartialView传过来的ControllerName,你给他加上你自己的规则,那他就会生成对应的路径啦。

你看FindView里面的这句 

ViewEngineResult result = FindThemeableView(controllerContext, ViewName, masterName, useCache);

很明显的,他是在拼路径,我们只要在这里,把viewName改成ViewName.Mobile就完了。

代码如下:

复制代码
 1   /// <summary>
 2         /// 判断当前请求是不是从手机端过来的
 3         /// </summary>
 4         /// <param name="httpContext">HTTP context</param>
 5         /// <returns>Result</returns>
 6         public virtual bool IsMobileDevice(HttpContextBase httpContext)
 7         {
 8             //comment the code below if you want tablets to be recognized as mobile devices.
 9             //nopCommerce uses the free edition of the 51degrees.mobi library for detecting browser mobile properties.
10             //by default this property (IsTablet) is always false. you will need the premium edition in order to get it supported.
11             bool isTablet = false;
12             if (bool.TryParse(httpContext.Request.Browser["IsTablet"], out isTablet) && isTablet)
13                 return false;
14 
15             if (httpContext.Request.Browser.IsMobileDevice)
16                 return true;
17 
18             return false;
19         }
复制代码
复制代码
 1 /// <summary>
 2         /// 返回View视图
 3         /// </summary>
 4         /// <param name="controllerContext"></param>
 5         /// <param name="viewName"></param>
 6         /// <param name="masterName"></param>
 7         /// <param name="useCache"></param>
 8         /// <returns></returns>
 9         public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
10         {
11             bool useMobileDevice = IsMobileDevice(controllerContext.HttpContext);//判断请求是否从手机过来
12             string overrideViewName = useMobileDevice ?
13                 string.Format("{0}.{1}", viewName, _mobileViewModifier)
14                 : viewName;//拼路径_mobileViewModifier这是个string类型的变量,你也可以直接写死称Mobile或者Wap等等,到时候,你就是viewName._mobileViewModifier.cshtml
15             ViewEngineResult result = FindThemeableView(controllerContext, overrideViewName, masterName, useCache);//找一下视图
16             if (useMobileDevice && (result == null || result.View == null))
17                 result = FindThemeableView(controllerContext, viewName, masterName, useCache);//没找到,再去找没有带后缀的试图
18             return result;
19         }
复制代码
复制代码
 1 public override ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
 2         {
 3             bool useMobileDevice = IsMobileDevice(controllerContext.HttpContext);
 4             string overrideViewName = useMobileDevice ?
 5                 string.Format("{0}.{1}", partialViewName, _mobileViewModifier)
 6                 : partialViewName;
 7             ViewEngineResult result = FindThemeablePartialView(controllerContext, overrideViewName, useCache);
 8             if (useMobileDevice && (result == null || result.View == null))
 9             result = FindThemeablePartialView(controllerContext, partialViewName, useCache);
10             return result;
11         }
复制代码