在ASP.NET Core Mvc中使用 IViewLocationExpander

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

我想从自定义位置呈现视图,为此我在一个类中实现了 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;
    }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值