Razor view engine location order not honored?

2019-09-06 03:16发布

I created a RazorViewEngine subclass to redefine where it looks for views.

I set PartialViewLocationFormats string array to contain values

"~/Views/{1}/{0}.cshtml",
"~/Views/{1}/Partial/{0}.cshtml",
"~/Views/Shared/{0}.cshtml",

The first and last are there by default. The 2nd one is the one I added, so that I could have a "Partial" subfolder in each "Views/ControllerName" folder for partial views used only by views within that controller, rather than adding them to the "Views/Shared" folder.

The issue I'm encountering is that calling @Html.Partial("_TopNavbar") is finding and rendering the '_TopNavbar.cshtml" file that's in the "Views/Shared" folder, rather than in the one under my DashBoards's "Views/Dashboard/Partial" folder.

In other words, there are two different files named "_TopNavbar.cshtml" in two different folders, and I'm expecting it to be found in one location because it's more specific and occurs first in the array, but it's not working that way for some reason I don't understand.

The Partial call is inside "Views/Dashboard/Index.cshtml', and I'm accessing it by directly navigating to "localhost:port/Dashboard/Index", so I'm sure the controller and action are correct.

1条回答
Emotional °昔
2楼-- · 2019-09-06 03:59

I have had success using a subclassed RazorViewEngine that only looks for C# views. I extended it to look in a specific controller folder for partials.

Using the CustomRazorViewEngine below and requesting /Home/Index which is calling Html.Partial("_SomePartial") inside it's view will look for partials in this order:

  1. /Views/Home/Partials/_SomePartial.cshtml
  2. /Views/Home/_SomePartial.cshtml
  3. /Views/Shared/_SomePartial.cshtml

This is indeed returning the the partial views in the correct order.

public class CustomRazorViewEngine : RazorViewEngine
{
    public CustomRazorViewEngine()
    {
        ViewLocationFormats = new[]
        {
            "~/Views/{1}/{0}.cshtml",
            "~/Views/Shared/{0}.cshtml"
        };

        MasterLocationFormats = ViewLocationFormats;

        PartialViewLocationFormats = new[]
        {
            "~/Views/{1}/Partials/{0}.cshtml",
            "~/Views/{1}/{0}.cshtml",
            "~/Views/Shared/{0}.cshtml"
        };
    }
}

Make sure that you are only using your subclassed view engine by clearing all existing and adding your new custom view engine.

Global.asax.cs

ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new CustomRazorViewEngine());
查看更多
登录 后发表回答