Override razor views in asp.net core razor pages

2.4k views Asked by At

In asp.net core mvc, I had multiple locations specified for the views. so, if view was missing in one location, it gets fetched from the other location.

I have a CMS with asp.net core mvc where controllers and views comes in a compiled library. If I don't want to use the view from the library, it's easy to add a new one e.g. /Views/ControllerName/Index.cshtml and then the application will use this view instead of fetching from the library.

How can it be done in razor pages? Basically, I want to have an option to override the razor view of any page by adding a .cshtml file in a location.

2

There are 2 answers

2
Will Ray On

Use an IViewLocationExpander, adding your custom location(s) before the default ones.

Here's an example that would look into an "Override" folder:

public class MyViewLocationExpander : IViewLocationExpander
{
    public IEnumerable<string> ExpandViewLocations(
        ViewLocationExpanderContext context,
        IEnumerable<string> viewLocations)
    {
        // {2} = Area
        // {1} = Controller
        // {0} = Action
        var locations = new string[] { "/Views/Override/{2}/{1}/{0}.cshtml" };
        return locations.Union(viewLocations);
    }

    public void PopulateValues(ViewLocationExpanderContext context)
    {
    }
}

Then register it in your Startup class:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<RazorViewEngineOptions>(options =>
    {
        options.ViewLocationExpanders.Add(new MyViewLocationExpander());
    });
}
0
hankor On

I didn't get this to work in ASP.NET Core 2.2 using the other solutions suggested here (IViewLocationExpander or PageViewLocationFormats). What worked for me was using a PageRouteModelConvention in combination with an ActionConstraint.

Here's a similar solution where this has been used for localization: