How do I make MVC look for razor and webforms views in the Views/Shared folder last?
I have an older ASP.NET MVC application that uses classic web forms views. As an experiment, we've started to mix in some razor views. Unfortunately, the default precedence for where to find the desired view isn't what I want. MVC first looks in your /Views/ControllerName folder for aspx and ascx files. Then it moves to your /Views/Shared for aspx and ascx files. Then it starts over looking for .cshtml and .vbhtml files. What I want is for it not开发者_如何学Python to go into the Shared folder until it's exhausted all the possibilities in the /Views/ControllerName folder. How do I do this?
--- UPDATE ---
Here's some additional information that might help explain what I'm after. By default, I get this search order:
~/Views/Home/Index.aspx
~/Views/Home/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
~/Views/Home/Index.cshtml
~/Views/Home/Index.vbhtml
~/Views/Shared/Index.cshtml
~/Views/Shared/Index.vbhtml
What I want is this:
~/Views/Home/Index.aspx
~/Views/Home/Index.ascx
~/Views/Home/Index.cshtml
~/Views/Home/Index.vbhtml
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
~/Views/Shared/Index.cshtml
~/Views/Shared/Index.vbhtml
In other words, it shouldn't search Shared before it searches the /Views/ControllerName folder completely.
You can configure the precedence of view engines in your global.asax.cs file
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new RazorViewEngine());
ViewEngines.Engines.Add(new WebFormViewEngine());
}
After toying with it a bit, I was able to achieve what I wanted with a simple Fluent API. The extension methods remove the search locations I didn't want from each of the view engines. The search locations are stored in .ViewLocationFormats
and .PartialViewLocationFormats
string arrays. So here's the fluent API that removes the unwanted items from those arrays:
public static class BuildManagerViewEngineFluentExtensions {
public static BuildManagerViewEngine ControllerViews(this BuildManagerViewEngine engine) {
return FilterViewLocations(engine, x => x.Contains("/Views/Shared/") == false);
}
public static BuildManagerViewEngine SharedViews(this BuildManagerViewEngine engine) {
return FilterViewLocations(engine, x => x.Contains("/Views/Shared/") == true);
}
private static BuildManagerViewEngine FilterViewLocations(BuildManagerViewEngine engine, Func<string, bool> whereClause) {
engine.ViewLocationFormats = engine.ViewLocationFormats.Where(whereClause).ToArray();
engine.PartialViewLocationFormats = engine.PartialViewLocationFormats.Where(whereClause).ToArray();
return engine;
}
}
And then, in my global.asax, I added the following lines to protected void Application_Start()
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new RazorViewEngine().ControllerViews());
ViewEngines.Engines.Add(new WebFormViewEngine().ControllerViews());
ViewEngines.Engines.Add(new RazorViewEngine().SharedViews());
ViewEngines.Engines.Add(new WebFormViewEngine().SharedViews());
精彩评论