简体   繁体   中英

Razor Class Library doesn't include Views in DLL

I have an ASP.Net Core MVC application (written in F#) using .Net Core 3 that has the views in an external Razor Class Library (because you can't mix C# and F#), however, when I run the application the views are not found.

The MVC application does have a reference to the class-library however when I looked at the class-library DLL using dotPeek it did not have any compiled views in it:

dotPeek 反汇编

This is the csproj of the Razor class library:

<Project Sdk="Microsoft.NET.Sdk.Razor">
  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
    <AddRazorSupportForMvc>true</AddRazorSupportForMvc>
  </PropertyGroup>

  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\SportsStore.Infrastructure\SportsStore.Infrastructure.fsproj" />
    <ProjectReference Include="..\SportsStore.Models\SportsStore.Models.fsproj" />
    <ProjectReference Include="..\SportsStore.TagHelpers\SportsStore.TagHelpers.fsproj" />
  </ItemGroup>
</Project>

And there are Views in the project:

Razor 类库解决方案资源管理器

I am guessing that the csproj file is most likely wrong, but how can I fix it?

View are embedded resources in the RCL. You access them just as if they were physically in the project at the same filesystem locations. The issue here, I think, is that you have the views at the project root instead of under Views / Pages , which is where views will be searched for by convention.

You can alter that convention, but you'd need to then do that on every project that uses this RCL, and it's going to be complicated, because you'll need to add each folder individually as a separate location for searching for views, since there's no common root folder. The better solution is to follow the convention and actually put your views under a Views directory. In other words, instead of {project root}/Shared/_Layout.cshtml , it should be {project root}/Views/Shared/_Layout.cshtml .

If you really want to do it you can like this:

In API project (csproj, fproj) force razor files to be excluded from compile at build, and make sure compiling at runtime will work (all razor and C# dependencies)

<MvcRazorCompileOnPublish>false</MvcRazorCompileOnPublish>
<MvcRazorExcludeRefAssembliesFromPublish>false</MvcRazorExcludeRefAssembliesFromPublish>

Now we have to make sure that at build or publish views are copied. So for any view in project (csproj) where is declared manually you have to add this

 <None Include="Account\Login.cshtml">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>

But then again, this approach is when you want to compile yourself the views, for example for a email generation or for a document generation, so I don't think this is what you are looking. Truly if you need it for a controller action result, view is compiled in project assembly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM