The new DisplayMode engine in ASP.NET MVC 4 is rather nice. By default, it will detect whether you come in from a mobile device or a desktop machine, and load up a specialized view for you based on that detection.
For example, if you were trying to navigate to http://www.example.com/Players from an iPhone, the default behavior will be to look for Players\Index.Mobile.cshtml, followed by Players\Index.cshtml. Whichever it finds first will be the view that gets used. Note that this also requires you to have a _Layout.Mobile.cshtml file.
This is great for new projects, but I have a non-trivial app with a lot of views that have been built over the years using the technique by Scott Hanselman
. That approach would look for the file in Players\Mobile\Index.cshtml. I was not looking forward to renaming all of those files.
In order to use my already existing file structure, I added one class:
public class SubfolderDisplayMode : DefaultDisplayMode
public SubfolderDisplayMode() : base("Mobile")
// Be sure to use 51degrees.mobi, or a good browser capabilities file
ContextCondition = (context => context.GetOverriddenBrowser().IsMobileDevice);
protected override string TransformPath(string virtualPath, string suffix)
var dir = VirtualPathUtility.GetDirectory(virtualPath);
var filename = VirtualPathUtility.GetFileName(virtualPath);
return VirtualPathUtility.Combine(dir, "Mobile/" + filename);
Registered it in my Globabl.asax.cs:
DisplayModeProvider.Instance.Modes.Insert(0, new SubfolderDisplayMode());
It works very well, and I can come back and rename those files later.
Also be sure to put a call to @Html.Partial("_VewSwitcher") somewhere in your desktop _Layou.cshtml file so the user can get back to the mobile version of the site.
Updated on 11/9/12 to clean the sample code up a bit