I want to render views from a custom location, so for that I have implemented the
IViewLocationExpander
interface in a class. I have registered the same class in Startup
class as follows.
Startup
Class
public void ConfigureServices(IServiceCollection services)
{
…
//Render view from custom location.
services.Configure<RazorViewEngineOptions>(options =>
{
options.ViewLocationExpanders.Add(new CustomViewLocationExpander());
});
…
}
CustomViewLocationExpander
Class
public class CustomViewLocationExpander : IViewLocationExpander
{
public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
{
var session = context.ActionContext.HttpContext.RequestServices.GetRequiredService<SessionServices>();
string folderName = session.GetSession<string>("ApplicationType");
viewLocations = viewLocations.Select(f => f.Replace("/Views/", "/" + folderName + "/"));
return viewLocations;
}
public void PopulateValues(ViewLocationExpanderContext context)
{
}
}
And, finally, my application’s views are organized as follows:
My issue: If I access the Views/Login
view from the ViewsFrontend
folder from the following URL:
http://localhost:56739/trainee/Login/myclientname
But then immediately change the URL in the browser to:
http://localhost:56739/admin/Login/myclientname
In this case, it still refers to the ViewsFrontend
folder, even though it should now refer to the ViewsBackend
folder, since URLs beginning with trainee
should refer to the ViewsFrontend
folder, while those beginning with admin
should refer to the ViewsBackend
folder.
Further, after changing the URL in the browser, it only calls the PopulateValues()
method, but not the ExpandViewLocations()
method.
How can I reconfigure this class to work for this other folder?
PopulateValues
exists as a way to specify parameters that your view lookup would vary by on a per-request basis. Since you're not populating it, the view engine uses cached values from an earlier request.
To solve this, add your ApplicationType
variable to the PopulateValues()
method and the ExpandValues()
method should get called whenever that value changes:
public class CustomViewLocationExpander : IViewLocationExpander
{
public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
{
string folderName = context.Values["ApplicationType"];
viewLocations = viewLocations.Select(f => f.Replace("/Views/", "/" + folderName + "/"));
return viewLocations;
}
public void PopulateValues(ViewLocationExpanderContext context)
{
var session = context.ActionContext.HttpContext.RequestServices.GetRequiredService<SessionServices>();
string applicationType = session.GetSession<string>("ApplicationType");
context.Values["ApplicationType"] = applicationType;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With