0

I've read several tutorials that explain how to replace the default path to the views folder in the case that the views folder needs to be moved. However, I've been trying to figure out how to add a path that is searched by the view engine.

Here's what I have so far:

public class BetterViewEngine : IViewLocationExpander
{
    public void PopulateValues(ViewLocationExpanderContext context)
    {
    }

    public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
    {
        return viewLocations.Select(s => s.Add("")); //Formerly s.Replace("oldPath", "newPath" but I wish to add
    }
}

And in my Startup.cs

services.AddMvc().AddRazorOptions(options =>
        {
            options.ViewLocationExpanders.Add(new BetterViewEngine());
        });
  • You want to change default location for views? – Sirwan Afifi Aug 07 '16 at 05:14
  • See this post: [Can I specify a custom location to “search for views” in ASP.NET MVC](http://stackoverflow.com/questions/632964/can-i-specify-a-custom-location-to-search-for-views-in-asp-net-mvc) – Mazaher Bazari Aug 07 '16 at 05:15

2 Answers2

1

If you want to change default behavior for searching the views, try this:

public class BetterViewEngine : IViewLocationExpander
{
   public void PopulateValues(ViewLocationExpanderContext context)
   {
        context.Values["customviewlocation"] = nameof(BetterViewEngine);
   }

   public IEnumerable<string> ExpandViewLocations(
        ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
   {
        return new[]
        {
             "/folderName/{1}/{0}.cshtml",
             "/folderName/Shared/{0}.cshtml"
        };
   }
}

But if you just want to rename one of the folders try this:

public IEnumerable<string> ExpandViewLocations(
      ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
{

      // Swap /Shared/ for /_Shared/
      return viewLocations.Select(f => f.Replace("/Shared/", "/_Shared/"));

}
Sirwan Afifi
  • 10,654
  • 14
  • 63
  • 110
  • I wasn't looking to change the default location. I just needed the engine to search one more place other than the default. In either case, your example would work. Thanks –  Aug 08 '16 at 04:02
  • How can i pass additional information to the view path? For example i want to have the following path: "/folderName/{1}/{0}.{2}.cshtml" where {2} is a placeholder for the current culture (e.g. en-US)? My problem is that i want to return a "localized" view if it does exists (/folderName/Home/Index.en-US.cshtml) or return default view (/folderName/Home/Index.cshtml) otherwise. Is there any simple solution for this case? Thanks. – Laserson Feb 13 '18 at 13:14
0

This is just expanding on Sirwan's answer since it took me a minute to figure out what I needed to do after reading the first part of his answer:

public class ViewLocationRemapper : IViewLocationExpander
{
    public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
    {
        return new[]
        {
            "/Views/{1}/{0}.cshtml",
            "/Views/Shared/{0}.cshtml",
            "/Views/" + context.Values["admin"] + "/{1}/{0}.cshtml"
        };
    }

    public void PopulateValues(ViewLocationExpanderContext context)
    {
        context.Values["admin"] = "AdminViews";
    }
}
Crob
  • 599
  • 4
  • 26