使用自定义位置时如何在asp.net core mvc中指定视图位置?

2024-01-01

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

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

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

        return View();
    }
}

现在假设我想将视图组织在一个文件夹结构中,该结构大致反映了它们相关的 url 路径。所以我希望该控制器的视图位于此处:

/Views/Admin/Product.cshtml

更进一步,如果我有一个像这样的控制器:

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

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

        return View();
    }
}

我希望框架能够自动在此处查找它的视图:

Views/Admin/Marketing/PromoCodeList.cshtml

理想情况下,用于向框架通知视图位置的方法将以基于基于属性的路由信息​​的一般方式工作,而不管涉及多少个url段(即,其嵌套的深度)。

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


好消息...在 ASP.NET Core 2 及更高版本中,您不再需要自定义 ViewEngine 甚至 ExpandViewLocations。

使用 OdeToCode.AddFeatureFolders 包

这是最简单的方法... K. Scott Allen 在 OdeToCode.AddFeatureFolders 为您提供了一个 nuget 包,它很干净,并且包含对区域的可选支持。 GitHub:https://github.com/OdeToCode/AddFeatureFolders https://github.com/OdeToCode/AddFeatureFolders

安装软件包,就这么简单:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc()
                .AddFeatureFolders();

        ...
    }

    ...
}  

DIY

如果您需要对文件夹结构进行极其精细的控制,或者如果您出于某种原因不允许/不想获取依赖项,请使用此选项。这也很简单,尽管可能比上面的 nuget 包更混乱:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
         ...

         services.Configure<RazorViewEngineOptions>(o =>
         {
             // {2} is area, {1} is controller,{0} is the action    
             o.ViewLocationFormats.Clear(); 
             o.ViewLocationFormats.Add("/Controllers/{1}/Views/{0}" + RazorViewEngine.ViewExtension);
             o.ViewLocationFormats.Add("/Controllers/Shared/Views/{0}" + RazorViewEngine.ViewExtension);

             // Untested. You could remove this if you don't care about areas.
             o.AreaViewLocationFormats.Clear();
             o.AreaViewLocationFormats.Add("/Areas/{2}/Controllers/{1}/Views/{0}" + RazorViewEngine.ViewExtension);
             o.AreaViewLocationFormats.Add("/Areas/{2}/Controllers/Shared/Views/{0}" + RazorViewEngine.ViewExtension);
             o.AreaViewLocationFormats.Add("/Areas/Shared/Views/{0}" + RazorViewEngine.ViewExtension);
        });

        ...         
    }

...
}

就是这样!无需特殊课程。

处理 Reshaper/Rider

额外提示:如果您使用 ReSharper,您可能会注意到在某些地方 ReSharper 无法找到您的视图,并会向您发出烦人的警告。要解决这个问题,请引入 Resharper.Annotations 包,并在您的startup.cs(或其他任何地方)中为每个视图位置添加以下属性之一:

[assembly: AspMvcViewLocationFormat("/Controllers/{1}/Views/{0}.cshtml")]
[assembly: AspMvcViewLocationFormat("/Controllers/Shared/Views/{0}.cshtml")]

[assembly: AspMvcViewLocationFormat("/Areas/{2}/Controllers/{1}/Views/{0}.cshtml")]
[assembly: AspMvcViewLocationFormat("/Controllers/Shared/Views/{0}.cshtml")]

希望这能让一些人免受我刚刚经历的沮丧时光的困扰。 :)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用自定义位置时如何在asp.net core mvc中指定视图位置? 的相关文章

随机推荐