使用自定义位置时,如何在asp.net core mvc中指定视图位置? [英] How to specify the view location in asp.net core mvc when using custom locations?

查看:89
本文介绍了使用自定义位置时,如何在asp.net core mvc中指定视图位置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个控制器,该控制器使用基于属性的路由来处理/admin/product的请求网址,如下所示:

Let's say I have a controller that uses attribute based routing to handle a requested url of /admin/product like so:

[Route("admin/[controller]")]        
public class ProductController: Controller {

    // GET: /admin/product
    [Route("")]
    public IActionResult Index() {

        return View();
    }
}

现在让我们说,我想将视图组织在一个文件夹结构中,该结构可以大致反映它们所关联的url路径.因此,我希望此控制器的视图位于此处:

Now let's say that I'd like to keep my views organized in a folder structure that roughly reflects the url paths they are related to. So I'd like the view for this controller to be located here:

/Views/Admin/Product.cshtml

如果我有一个像这样的控制器,那就走得更远:

To go further, if I had a controller like this:

[Route("admin/marketing/[controller]")]        
public class PromoCodeListController: Controller {

    // GET: /admin/marketing/promocodelist
    [Route("")]
    public IActionResult Index() {

        return View();
    }
}

我希望框架自动在此处查看其视图:

I would like the framework to automatically look for it's view here:

Views/Admin/Marketing/PromoCodeList.cshtml

理想情况下,不管涉及多少个URL段(即,嵌套深度如何),基于视图属性的路由信息​​,以一种通用的方式通知视图位置的方法都是可行的.

Ideally the approach for informing the framework of the view location would work in a general fashion based on the attribute based route information regardless of how many url segments are involved (ie. how deeply nested it is).

如何指示Core MVC框架(我目前正在使用RC1)在这样的位置查找控制器的视图?

How can I instruct the the Core MVC framework (I'm currently using RC1) to look for the controller's view in such a location?

推荐答案

您可以通过实现视图位置扩展器来扩展视图引擎查找视图的位置.这是一些示例代码来演示此方法:

You can expand the locations where the view engine looks for views by implementing a view location expander. Here is some sample code to demonstrate the approach:

public class ViewLocationExpander: IViewLocationExpander {

    /// <summary>
    /// Used to specify the locations that the view engine should search to 
    /// locate views.
    /// </summary>
    /// <param name="context"></param>
    /// <param name="viewLocations"></param>
    /// <returns></returns>
    public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations) {
        //{2} is area, {1} is controller,{0} is the action
        string[] locations = new string[] { "/Views/{2}/{1}/{0}.cshtml"};
        return locations.Union(viewLocations);          //Add mvc default locations after ours
    }


    public void PopulateValues(ViewLocationExpanderContext context) {
        context.Values["customviewlocation"] = nameof(ViewLocationExpander);
    }
}

然后在startup.cs文件的ConfigureServices(IServiceCollection services)方法中添加以下代码以将其注册到IoC容器.在services.AddMvc();

Then in the ConfigureServices(IServiceCollection services) method in the startup.cs file add the following code to register it with the IoC container. Do this right after services.AddMvc();

services.Configure<RazorViewEngineOptions>(options => {
        options.ViewLocationExpanders.Add(new ViewLocationExpander());
    });

现在,您可以将所需的任何自定义目录结构添加到视图引擎查找视图和部分视图的位置列表中.只需将其添加到locations string[].另外,您可以将_ViewImports.cshtml文件放置在同一目录或任何父目录中,并且该文件将被找到并与位于此新目录结构中的视图合并.

Now you have a way to add any custom directory structure you want to the list of places the view engine looks for views, and partial views. Just add it to the locations string[]. Also, you can place a _ViewImports.cshtml file in the same directory or any parent directory and it will be found and merged with your views located in this new directory structure.

更新:
这种方法的优点是,它提供了比后来在ASP.NET Core 2中引入的方法更大的灵活性(感谢@BrianMacKay记录了新方法).因此,例如,这种ViewLocationExpander方法不仅可以指定用于搜索视图和区域的路径层次结构,还可以指定布局和视图组件.此外,您还可以访问完整的ActionContext来确定适当的路由.这提供了很大的灵活性和力量.因此,例如,如果您想通过评估当前请求的路径来确定适当的视图位置,则可以通过context.ActionContext.HttpContext.Request.Path访问当前请求的路径.

Update:
One nice thing about this approach is that it provides more flexibility then the approach later introduced in ASP.NET Core 2 (Thanks @BrianMacKay for documenting the new approach). So for example this ViewLocationExpander approach allows for not only specifying a hierarchy of paths to search for views and areas but also for layouts and view components. Also you have access to the full ActionContext to determine what an appropriate route might be. This provides alot of flexibility and power. So for example if you wanted to determine the appropriate view location by evaluating the path of the current request, you can get access to the path of the current request via context.ActionContext.HttpContext.Request.Path.

这篇关于使用自定义位置时,如何在asp.net core mvc中指定视图位置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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