在MVC中使用IViewLocationExpander [英] Working with IViewLocationExpander in mvc

查看:86
本文介绍了在MVC中使用IViewLocationExpander的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从自定义位置呈现视图,因此我已经实现了 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆