Please be gentle with me, this is my first question on StackOverflow following many years of lurking.
I have an MVC4 site already up and running. I am adding mobile support to the site which is all going well using the standard MVC functionality:
I need some code to allow the framework to use Layout.cshtml if there is no ".Phone" version of the view
I have the following files:
Views/Home/HasBoth.cshtml
Views/Home/HasBoth.Phone.cshtml
Views/Shared/Layout.cshtml
Views/Shared/Layout.Phone.cshtml
This is great.
Again, this is also great.
I have the following files:
Views/Home/HasNoPhone.cshtml
Views/Shared/Layout.cshtml
Views/Shared/Layout.Phone.cshtml
Note: there is no Views/Home/HasNoPhone.Phone.cshtml
This is great.
The above is what I want to acheive.
Thanks to Zoka, I am now using the following for anyone else who wishes to do something similar:
Helper method:
/// <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>
...
Thanks again all.
As I understand your question, you need to find out if some view exists. I use such function placed in any class accessible from views:
public static bool ViewExists(string _name, ControllerContext _controller_context)
{
ViewEngineResult result = ViewEngines.Engines.FindView(_controller_context, _name, null);
return (result.View != null);
}
Then put this into _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"
}
And finally in Layout.cshml (respectively in Layout.Phone.cshtml), instead of call to 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 *@
You could use an existing jquery mobile package:
Edit: Maybe you could use a page installer and register your pages in a container. That way your controller can ask your container which view he should return.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.