RazorLight.Compilation 异常:无法编译生成的 Razor 模板

问题描述

我正在创建一个 .NET 5 worker service 应用程序,该应用程序很少会查看其他应用程序并在需要时发送电子邮件。 我正在使用 FluentEmail 发送这些电子邮件,一切正常,直到我部署应用程序。

当我部署应用程序并尝试发送电子邮件时,它抛出此异常:

RazorLight.Compilation.TemplateCompilationException: Failed to compile generated Razor template:
- (3:35) The type 'Attribute' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Private.CoreLib,Version=5.0.0.0,Culture=neutral,PublicKeyToken=7cec85d7bea7798e'.
- (3:10) The type 'Type' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Private.CoreLib,PublicKeyToken=7cec85d7bea7798e'.
- (35:37) The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Private.CoreLib,PublicKeyToken=7cec85d7bea7798e'.
- (38:66) 'GeneratedTemplate.ExecuteAsync()': return type must be 'Task' to match overridden member 'TemplatePageBase.ExecuteAsync()'
- (38:66) The type 'Task' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Private.CoreLib,PublicKeyToken=7cec85d7bea7798e'.
- (40:12) The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Private.CoreLib,PublicKeyToken=7cec85d7bea7798e'.
- (41:12) The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Private.CoreLib,PublicKeyToken=7cec85d7bea7798e'.
- (42:12) The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Private.CoreLib,PublicKeyToken=7cec85d7bea7798e'.
- (43:12) The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Private.CoreLib,PublicKeyToken=7cec85d7bea7798e'.
- (53:12) The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Private.CoreLib,PublicKeyToken=7cec85d7bea7798e'.
- (69:12) The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Private.CoreLib,PublicKeyToken=7cec85d7bea7798e'.
- (84:12) The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Private.CoreLib,PublicKeyToken=7cec85d7bea7798e'.
- (44:19) The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Private.CoreLib,PublicKeyToken=7cec85d7bea7798e'.
- (92:12) The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Private.CoreLib,PublicKeyToken=7cec85d7bea7798e'.
- (47:20) The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Private.CoreLib,PublicKeyToken=7cec85d7bea7798e'.
- (100:12) The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Private.CoreLib,PublicKeyToken=7cec85d7bea7798e'.
- (50:20) The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Private.CoreLib,PublicKeyToken=7cec85d7bea7798e'.
- (108:12) The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Private.CoreLib,PublicKeyToken=7cec85d7bea7798e'.
- (53:19) The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Private.CoreLib,PublicKeyToken=7cec85d7bea7798e'.
- (116:12) The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Private.CoreLib,PublicKeyToken=7cec85d7bea7798e'.
- (124:12) The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Private.CoreLib,PublicKeyToken=7cec85d7bea7798e'.
See CompilationErrors for detailed information
   at RazorLight.Compilation.RoslynCompilationService.CompileAndEmit(IGeneratedRazorTemplate razorTemplate)
   at RazorLight.Compilation.RazorTemplateCompiler.CompileAndEmit(RazorLightProjectItem projectItem)
   at RazorLight.Compilation.RazorTemplateCompiler.OnCacheMissAsync(String templateKey)
--- End of stack trace from prevIoUs location ---
   at RazorLight.EngineHandler.CompileTemplateAsync(String key)
   at RazorLight.EngineHandler.CompileRenderAsync[T](String key,T model,ExpandoObject viewBag)
   at CallSite.Target(Closure,CallSite,Object )
   at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site,T0 arg0)
   at FluentEmail.Razor.RazorRenderer.ParseAsync[T](String template,Boolean isHtml)
   at FluentEmail.Razor.RazorRenderer.FluentEmail.Core.Interfaces.ITemplateRenderer.Parse[T](String template,Boolean isHtml)
   at FluentEmail.Core.Email.UsingTemplateFromFile[T](String filename,Boolean isHtml)
   at WatchDog.Services.NotificationService.SendEmailAsync[TModel](String subject,String fileName,TModel model) in C:\Users\SomeOne\source\repos\WatchDog\WatchDog\Services\NotificationService.cs:line 41

我的设置如下:

查看文件 参考资料

查看文件

添加了 Views 文件夹,请注意这是一个 .NET 5 Worker Service 项目(如果这很重要而不是某个 Web 项目)。

Program.cs 文件

在 ConfigureServices 中,我已将 RazorRenderer 添加为:

//Set email service using FluentEmail
 services.AddFluentEmail("appname@domain.com")
 .AddRazorRenderer(@$"{Directory.GetCurrentDirectory()}/Views/")
 .AddSmtpSender("smtp.somesmtp.com",25)
 .AddSmtpSender(new System.Net.Mail.SmtpClient() { });
NotificationService.cs 文件
private async Task SendEmailAsync<TModel>(string subject,TModel model)
{
    try
    {
        using (var scope = _serviceProvider.CreateScope())
        {
            var email = await scope.ServiceProvider.GetrequiredService<IFluentEmail>()
                    .To(string.Join(";",_emailRecipients))
                    .Subject(subject)
                    .UsingTemplateFromFile("./Views/Emails/SomeReport.cshtml",model)
                    .SendAsync();
        }
    }
    catch (Exception ex)
    {
        _logger.LogError(ex,"Failed to send email. Check exception for more information.");
    }
}
SomeReport.cshtml 文件

SomeReport.cshtml 位于 Views\Emails\SomeReport.cshtml 内,如下所示:

@using System.Collections.Generic;
@using WatchDog.Models;

@model IEnumerable<SomeReport>
@{
    Layout = "./Shared/_Layout.cshtml";
}

@* Work with the Model here... *@
_Layout.cshtml 文件

_Layout.cshtml 位于 Views\Shared\_Layout.cshtml 内,如下所示:

@* Some common layout styles here *@
@RenderBody()
WatchDog.csproj 文件

我还添加PreserveCompilationContextPreserveCompilationReferences

<PropertyGroup>
  <TargetFramework>net5.0</TargetFramework>
  <PreserveCompilationContext>true</PreserveCompilationContext>
  <PreserveCompilationReferences>true</PreserveCompilationReferences>
</PropertyGroup>

我已经到处寻找,但仍然没有找到解决方案。 请帮忙。

谢谢!

解决方法

我遇到了完全相同的问题,但仅限于我已发布的应用程序中。在调试工作服务时,我没有收到错误消息。

为我修复的是从 p:PublishTrimmed=true 命令中删除 dotnet publish 属性。

为了完整起见,这就是我的 .csproj 文件的样子:

<PropertyGroup>
  <PreserveCompilationReferences>true</PreserveCompilationReferences>
  <PreserveCompilationContext>true</PreserveCompilationContext>
  <MvcRazorCompileOnPublish>false</MvcRazorCompileOnPublish>
  <MvcRazorExcludeRefAssembliesFromPublish>false</MvcRazorExcludeRefAssembliesFromPublish>
</PropertyGroup>

参考文献: