问题
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