How to specify the view location in asp.net core mvc when using custom locations?

前端 未结 8 2071
死守一世寂寞
死守一世寂寞 2020-11-30 22:59

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



        
相关标签:
8条回答
  • 2020-11-30 23:45

    Great news... In ASP.NET Core 2 and up, you don't need a custom ViewEngine or even ExpandViewLocations anymore.

    Using the OdeToCode.AddFeatureFolders Package

    This is the easiest way... K. Scott Allen has a nuget package for you at OdeToCode.AddFeatureFolders that is clean and includes optional support for areas. Github: https://github.com/OdeToCode/AddFeatureFolders

    Install the package, and it's as simple as:

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

    DIY

    Use this if you need extremely fine control over your folder structure, or if you aren't allowed/don't want to take the dependency for whatever reason. This is also quite easy, although perhaps more cluttery than the nuget package above:

    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);
            });
    
            ...         
        }
    
    ...
    }
    

    And that's it! No special classes required.

    Dealing with Resharper/Rider

    Bonus tip: if you're using ReSharper, you might notice that in some places ReSharper can't find your views and gives you annoying warnings. To work around that, pull in the Resharper.Annotations package and in your startup.cs (or anywhere else really) add one of these attributes for each of your view locations:

    [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")]
    

    Hopefully this spares some folks the hours of frustration I just lived through. :)

    0 讨论(0)
  • 2020-11-30 23:50

    I am using core 3.1 and just do this inside of ConfigureServices method inside of Startup.cs.

     services.AddControllersWithViews().AddRazorOptions(
         options => {// Add custom location to view search location
             options.ViewLocationFormats.Add("/Views/Shared/YourLocation/{0}.cshtml");                    
         });
    

    the {0} is just a place holder for the view name. Nice and simple.

    0 讨论(0)
提交回复
热议问题