在Nop3.4中,他拋棄了原來的xxx.Mobile.cshtml的這種寫法,而是采用了響應式布局,並且把規則也給改了,你在后台配置不啟用響應式布局,在前台你仍然不能寫xxx.Mobile.cshtml這樣。查了一天的原因,終於查出來了。
首先請大家了解mvc4的新特征:http://www.cnblogs.com/egger/p/3400076.html
看完這個,估計你也會被誤導,認為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 }
