Razor 引擎在 .Net Core class 库中找不到我的视图

Razor engine can't find my view in .Net Core class library

我有我的 class 图书馆,其中包括 ViewRenderService class:

public interface IViewRenderService
    {
        Task<string> RenderToStringAsync(string viewName, object model);
    }

    public class ViewRenderService : IViewRenderService
    {
        private readonly IRazorViewEngine _razorViewEngine;
        private readonly ITempDataProvider _tempDataProvider;
        private readonly IServiceProvider _serviceProvider;

        public ViewRenderService(IRazorViewEngine razorViewEngine,
            ITempDataProvider tempDataProvider,
            IServiceProvider serviceProvider)
        {
            _razorViewEngine = razorViewEngine;
            _tempDataProvider = tempDataProvider;
            _serviceProvider = serviceProvider;
        }

        public async Task<string> RenderToStringAsync(string viewName, object model)
        {
            var httpContext = new DefaultHttpContext { RequestServices = _serviceProvider };
            var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());

            using (var sw = new StringWriter())
            {
                var viewResult = _razorViewEngine.FindView(actionContext, viewName, false);

                if (viewResult.View == null)
                {
                    throw new ArgumentNullException($"{viewName} does not match any available view");
                }

                var viewDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary())
                {
                    Model = model
                };

                var viewContext = new ViewContext(
                    actionContext,
                    viewResult.View,
                    viewDictionary,
                    new TempDataDictionary(actionContext.HttpContext, _tempDataProvider),
                    sw,
                    new HtmlHelperOptions()
                );

                await viewResult.View.RenderAsync(viewContext);
                return sw.ToString();
            }
        }

和很多观点,从路径开始:my class library root/Views//Shared/many views.

问题是,IRazorViewEngine找不到我的视图,我应该如何调用viewRenderService.RenderToStringAsync(?)来渲染~/Views/Shared/Myview.cshtml,例如?

我在 class 库中处理视图的方式是使视图嵌入资源,即在我拥有的 .csproj 文件中

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

你需要这个包:

<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="1.1.*" />

然后我的 class 库中有一个扩展方法,如下所示:

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

    return options;
}

然后在主应用程序的 Startup.cs 中,您必须选择使用如下扩展方法包含这些视图:

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

ASP.NET Core 2.0

更新

在您的库 .csproj 中,您应该具有以下内容(提及您的观点的所有其他内容都可以 removed/commented):

<Project Sdk="Microsoft.NET.Sdk.Razor">
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <Content Update="Views\xxx\_MyView.cshtml">
      <Pack>$(IncludeRazorContentInPack)</Pack>
    </Content>
  </ItemGroup>
</Project>

请注意替换 Content Includes=Content Update=,这让我很难找到问题所在 :)

以及正确嵌入视图的 Project Sdk="Microsoft.NET.Sdk.Razor".Razor

.Net Core 3.1 更新

我自己也遇到了同样的问题,苦苦挣扎了一段时间后,@Jean 的回答帮了大忙。这是我对该答案的 .Net Core 3.1 更新。希望对其他人有帮助。

这是在 .Net Core 3.1 class 库的 .csproj 文件中:

<Project Sdk="Microsoft.NET.Sdk.Razor">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>  
    <AddRazorSupportForMvc>true</AddRazorSupportForMvc>
  </PropertyGroup>

  <ItemGroup>
    <Content Update="Views\**\*.cshtml" />
  </ItemGroup>

</Project>

这是库中的文件结构。

要从 Web 应用调用库中的视图组件,请使用:

 @await Component.InvokeAsync("GoogleAnalytics")

我正在复制旧模板文件并替换内容,然后将它们添加到 csproj 中,就像这样... 这些都没有通过查找视图来获取。

评论它使它起作用

<ItemGroup>
    <Content Remove="EmailTemplates\ConfirmEmail.cshtml" />
    <Content Remove="EmailTemplates\ForgotPassword.cshtml" />
   
  </ItemGroup>