问题
I can't reuse my cshtml files from another assembly. Here's the bare-bone sample:
- Create an ASP.NET Core Web Application project with default template (using Web-Application, Model-View-Controller), and name it
ViewReuse
- Add a class library called
ViewLibrary
- Add a reference to
Microsoft.AspNetCore.All
metapackage in ViewLibrary - Create a folder called Views, then create another folder called Shared, and inside it create a simple cshtml file called
ReusedLayout.cshtml
- Add
EmbeddedResources Include='Views\**\*.cshtml'
to csproj of ViewLibrary, to include all views inside the ViewLibrary.dll - In ViewReuse project, inside Startup.cs, change configuration of MVC service to
services.AddMvc().ConfigureApplicationPartManager(p => { p.ApplicationParts.Add(new AssemblyPart(typeof(ReusedController).Assembly)); });
- Change
About.cshtml
to use the layout from ViewLibrary:Layout = "/Views/Shared/ReusedLayout.cshtml"
- Then run the application, and navigate to
/home/about
.
For me I encountered this error:
InvalidOperationException: The layout view '/Views/Shared/ReusedLayout.cshtml' could not be located. The following locations were searched: /Views/Shared/ReusedLayout.cshtml
What have I done wrong? How do I solve this issue?
回答1:
Try right-click over the view files and in properties change to embedded resource.
回答2:
I solved it by the following way:
Razor class library project
First I created a solution called RazorDll with a Razor dll library project and deleted everything in it. Now create the MVC structure for the views. For testing purpose, I added a file called _Layout2
there.
Also add an empty Startup
class in the project root for assembly detection later:
namespace RazorDll {
public class Startup {
}
}
Its important to have all Razor filed embedded! You have two ways of doing this:
Embedd all in the .csproj file properties
If you have a project just for embedding all Razor view, this is the best option since you don't have to edit file propertys for every view by hand. Just right click on the project and choose edit project file, or open the corresponding .csproj
file with any text editor and insert the following in <Project>
<ItemGroup>
<EmbeddedResource Include="Views\**\*.cshtml">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
</ItemGroup>
Embedd single Razor views by hand
Just right click on a Razor views .cshtml
file, choose properties and set the build action to embedded ressource. Required for every view you want to use from another .NET Core assembly.
Consuming MVC project for the Razor class library
Now create the MVC project, called MvcDemo
here. This is a normal ASP.NET Core 2.1 MVC project (choosed the LTS here, but should also work with 2.2) that got linked to our Razor dll
To search for Razor views in the Assembly, we add it in Startup.ConfigureServices
method:
var viewAssembly = typeof(RazorDll.Startup).GetTypeInfo().Assembly;
var fileProvider = new EmbeddedFileProvider(viewAssembly);
services.Configure<RazorViewEngineOptions>(options => {
options.FileProviders.Add(fileProvider);
});
Notice the full qualified type in typeof
to distinct between the Startup
class of the consuming MVC project (which would be loaded without namespace) and the Razor class library.
You're ready to change e.g. _ViewStart.cshtml
to consume our test _Layout2
from our Razor class library:
@{
Layout = "_Layout2";
}
Result of a simple POC demo project:
来源:https://stackoverflow.com/questions/48051478/embedded-view-can-not-be-found-in-asp-net-core-mvc