ASP.NET Core ViewLocationExpander can not find view in other assembly

六月ゝ 毕业季﹏ 提交于 2020-01-05 08:45:54

问题


I have following solution:

src
   /Web
   /Web.Admin
        /Controller
          /TestControllr.cs
        /Views
            /Test
               /Index.cshtml

I use Application Part for separate My application parts:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        var adminAssembly = Assembly.Load(new AssemblyName("Web.Admin"));

        services.AddMvc().AddApplicationPart(adminAssembly);

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

        });
    }
}

and create a ViewLocationExpander name of AdminViewLocationExpander:

public class AdminViewLocationExpander : IViewLocationExpander
{
    public void PopulateValues(ViewLocationExpanderContext context)
    {
    }

    public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
    {
        const string adminAssembly = "Web.Admin";

        var adminViewsLocations = new []
        {
            $"/{adminAssembly}/Views/{{1}}/{{0}}.cshtml",
            $"/{adminAssembly}/Views/Shared/{{0}}.cshtml"
        };

        viewLocations = adminViewsLocations.Concat(viewLocations);

        return viewLocations;
    }
}

When I run the application with this URL localhost:6046/Test/Index get following:

 InvalidOperationException: The view 'Index' was not found. The following 
 locations were searched:
 /Web.Admin/Views/Test/Index.cshtml
 /Web.Admin/Views/Shared/Index.cshtml
 /Views/Test/Index.cshtml
 /Views/Shared/Index.cshtml

How Can I Solve this?


回答1:


In my projects I keep views as embedded resources in separate class library projects/assembly, packaged as nugets. For example here is one project with embedded views.

I don't need a custom IViewLocationExpander to find them. Instead I create an extension method like this:

public static RazorViewEngineOptions AddCloudscribeSimpleContentBootstrap3Views(this RazorViewEngineOptions options)
{
    options.FileProviders.Add(new EmbeddedFileProvider(
                typeof(Bootstrap3).GetTypeInfo().Assembly,
                "cloudscribe.SimpleContent.Web.Views.Bootstrap3"
          ));

    return options;
} 

then in startup of the main app I add them like this:

services.AddMvc()
.AddRazorOptions(options =>
{
    options.AddCloudscribeSimpleContentBootstrap3Views();


});

In my class library with embedded views I just have them in a Views folder as normal, and in my .csproj file I make them embedded resources like this:

<ItemGroup>
<EmbeddedResource Include="Views\**" Exclude="bin\**;obj\**;**\*.xproj;packages\**;@(EmbeddedResource)" />
</ItemGroup>

They work the same as if they were on disk, and if I want to override/customize a view I can copy it locally and the local view will be used instead of the embedded one automatically.



来源:https://stackoverflow.com/questions/46380332/asp-net-core-viewlocationexpander-can-not-find-view-in-other-assembly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!