我想从自定义位置呈现视图,为此我在一个类中实现了 IViewLocationExpander 接口。 我在 Startup 类中注册了相同的类,如下所示。
Startup 类
public void ConfigureServices(IServiceCollection services)
{
…
//Render view from custom location.
services.Configure<RazorViewEngineOptions>(options =>
{
options.ViewLocationExpanders.Add(new CustomViewLocationExpander());
});
…
}
CustomViewLocationExpander 类
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)
{
}
}
最后,我的应用程序的视图组织如下:

我的问题:如果我从以下 URL 的 ViewsFrontend 文件夹访问 Views/Login 视图:
http://localhost:56739/trainee/Login/myclientname
但随后立即将浏览器中的 URL 更改为:
http://localhost:56739/admin/Login/myclientname
在这种情况下,它仍然引用 ViewsFrontend 文件夹,尽管它现在应该引用 ViewsBackend 文件夹,因为以 trainee 开头的 URL 应该引用 ViewsFrontend 文件夹,而以 admin 开头的 URL 应该引用 ViewsBackend 文件夹。
此外,在浏览器中更改 URL 后,它只调用 PopulateValues() 方法,而不调用 ExpandViewLocations() 方法。
我怎样才能重新配置这个类来为这个其他文件夹工作?
答案
PopulateValues 作为一种指定参数的方式存在,您的视图查找将根据每个请求而变化。 由于您没有填充它,因此视图引擎使用来自早期请求的缓存值。
要解决此问题,请将您的 ApplicationType 变量添加到 PopulateValues() 方法,并且只要该值发生变化,就会调用 ExpandValues() 方法:
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;
}
}

文章描述了一个在ASP.NETCore中实现IViewLocationExpander接口来从自定义位置加载视图的问题。当URL改变时,视图引擎仍然使用先前请求的缓存值。解决方案是通过在PopulateValues方法中添加ApplicationType到context.Values,确保每次ApplicationType变化时都会调用ExpandViewLocations。
288

被折叠的 条评论
为什么被折叠?



