Asp.Net MVC change view location for DisplayModeProvider
I am developing a huge web application with a lot of views. It is unacceptable to keep desktop or mobile views in the same folder. Is it possible to group mobile views (name.Mobile.cshtml) into an explicit subfolder and tell DisplayModeProvider to find them? For example,
Views/Home/Index.Mobile.cshtml
moves to Views/Home/Mobile/Index.Mobile.cshtml
Views/People/List.Mobile.cshtml
moves toViews/People/Mobile/List.Mobile.cshtml
source to share
Well, I found several ways to solve this problem.
-
I can implement a custom RazorViewEngine (WebFormViewEngine) and specify my own collection
ViewLocationFormats
. -
I can use scopes to achieve this behavior.
-
I can implement my own DefaultDisplayMode method and override the method
TransformPath()
to change the location of the views.
I think the third way is simpler and easier. Here is the code:
First, I create my own DisplayMode and inherit from DefaultDisplayMode:
public class NewDisplayMode : DefaultDisplayMode
{
public NewDisplayMode()
: base("Mobile") //any folder name you like, or you can pass it through parameter
{
}
public NewDisplayMode(string folderName)
: base(folderName) //any folder name you like, or you can pass it through parameter
{
}
protected override string TransformPath(string virtualPath, string suffix)
{
string view = Path.GetFileName(virtualPath);
string pathToView = Path.GetDirectoryName(virtualPath);
virtualPath = (pathToView + "\\" + suffix + "\\" + view).Replace("\\", "/");
return virtualPath;
}
}
In the above code, I override the method TransformPath()
and convert the string virtualPath
to change location to views.
Next, I need to add this mode to the collection of modes:
protected void Application_Start()
{
DisplayModeProvider.Instance.Modes.RemoveAt(0);
DisplayModeProvider.Instance.Modes.Insert(0, new NewDisplayMode()
{
ContextCondition = context => context.GetOverriddenBrowser().IsMobileDevice
//ContextCondition = context => context.Request.Url.Host == "www.m.mysite.com"
});
//other code
}
So I don't need to rename my view files, I use the same name for mobile and desktop views. Finally, the folder structure looks like this:
source to share