在MVC中使用IViewLocationExpander [英] Working with IViewLocationExpander in mvc
问题描述
我想从自定义位置呈现视图,因此我已经实现了
IViewLocationExpander
接口在一个类中.我已经在Startup
类中注册了相同的类,如下所示.
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
类
Startup
Class
public void ConfigureServices(IServiceCollection services)
{
…
//Render view from custom location.
services.Configure<RazorViewEngineOptions>(options =>
{
options.ViewLocationExpanders.Add(new CustomViewLocationExpander());
});
…
}
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:
我的问题:如果我从以下URL从ViewsFrontend
文件夹访问Views/Login
视图:
My issue: If I access the Views/Login
view from the ViewsFrontend
folder from the following URL:
http://localhost:56739/trainee/Login/myclientname
但是随后立即在浏览器中将URL更改为:
But then immediately change the URL in the browser to:
http://localhost:56739/admin/Login/myclientname
在这种情况下,它仍然引用ViewsFrontend
文件夹,即使现在应该引用ViewsBackend
文件夹,因为以trainee
开头的URL应该引用admin
开头的文件夹应引用ViewsBackend
文件夹.
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.
此外,在浏览器中更改URL后,它仅调用PopulateValues()
方法,而不调用ExpandViewLocations()
方法.
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
是一种用于指定参数的方法,您的视图查找将根据每个请求而变化.由于您没有在其中填充视图,因此视图引擎将使用早期请求中的缓存值.
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.
要解决此问题,请将您的ApplicationType
变量添加到PopulateValues()
方法中,并且只要该值发生更改,就应调用ExpandValues()
方法:
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;
}
}
这篇关于在MVC中使用IViewLocationExpander的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!