c# - .NET Core 3.1 Sdk.Worker 与 Sdk.Web Razor 模板?(Sdk.Web 做了什么来允许 Razor 模板?)
问题描述
我正在尝试使用这个示例来展示如何将 Razor 模板呈现为字符串,以便我可以将它们用于丰富的电子邮件模板。
https://github.com/aspnet/Entropy/tree/master/samples/Mvc.RenderViewToString
我已经根据这个 repo 更新了代码,它描述了如何将示例更新到 .NET Core 3.1
https://github.com/scottsauber/RazorHtmlEmails
我稍微改变了它,因为我正在尝试使用 BackgroundService Worker 来根据数据库更改执行渲染和传输。
根据这个问题的答案(Can a Worker Service be called and/or used inside an existing ASPNET.Core web project?)多个进程可以同时运行。所以我像这样设置我的主机构建器。
public static IHostBuilder CreateHostBuilder(string[] args)
{
return Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureServices((hostContext, services) =>
{
services.AddDbContext<MyDataContext>(dbOptions =>
{
dbOptions.UseSqlServer(
hostContext.Configuration.GetConnectionString("db"),
sqlOptions => sqlOptions.EnableRetryOnFailure()
);
});
// This is our main worker that will loop
services.AddHostedService<Worker>();
// Add NLog as the logging handler
services.AddLogging(loggingBuilder =>
{
loggingBuilder.ClearProviders();
loggingBuilder.SetMinimumLevel(LogLevel.Trace);
loggingBuilder.AddNLog(hostContext.Configuration);
});
})
// Add our template renderer
.ConfigureWebHostDefaults(builder =>
{
builder.UseStartup<RazorStartup>();
});
}
和我的 RazorBuilder 一样..
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IRazorViewToStringRenderer, RazorViewToStringRenderer>();
services.AddRazorPages();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
var factory = app.ApplicationServices.GetService<IServiceScopeFactory>();
using (var scope = factory.CreateScope())
{
var confirmAccountModel = new ConfirmAccountEmailViewModel($"NOOOOO");
var service = scope.ServiceProvider.GetService<IRazorViewToStringRenderer>();
var result = service.RenderViewToStringAsync("/Views/Emails/ConfirmAccount/ConfirmAccountEmail.cshtml", confirmAccountModel).Result;
Console.WriteLine(result);
}
}
这一切...... “工作” ......只要我将目标SDK从更改 <Project Sdk="Microsoft.NET.Sdk.Worker">
为<Project Sdk="Microsoft.NET.Sdk.Web">
但是当我这样做时,我ILogger
的工人失去了写入控制台的能力。所以很明显,他们Sdk.Worker
正在做一些他们Sdk.Web
没有做的设置。
当我使用时Sdk.Worker
,我收到关于无法找到视图的错误。这意味着那Sdk.Web
显然是在做一些Sdk.Worker
不是的事情。
System.AggregateException
HResult=0x80131500
Message=One or more errors occurred. (Unable to find view '/Views/Emails/ConfirmAccount/ConfirmAccountEmail.cshtml'. The following locations were searched:
/Views/Emails/ConfirmAccount/ConfirmAccountEmail.cshtml)
Source=System.Private.CoreLib
StackTrace:
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
at System.Threading.Tasks.Task`1.get_Result()
at CompoundAlertProcessor.RazorStartup.Configure(IApplicationBuilder app, IWebHostEnvironment env) in C:\Users\c.rice\Documents\Solutions\GIT\CompoundAlertProcessor\CompoundAlertProcessor\RazorStartup.cs:line 46
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at Microsoft.AspNetCore.Hosting.ConfigureBuilder.Invoke(Object instance, IApplicationBuilder builder)
at Microsoft.AspNetCore.Hosting.ConfigureBuilder.<>c__DisplayClass4_0.<Build>b__0(IApplicationBuilder builder)
at Microsoft.AspNetCore.Hosting.GenericWebHostBuilder.<>c__DisplayClass13_0.<UseStartup>b__2(IApplicationBuilder app)
at Microsoft.AspNetCore.Mvc.Filters.MiddlewareFilterBuilderStartupFilter.<>c__DisplayClass0_0.<Configure>g__MiddlewareFilterBuilder|0(IApplicationBuilder builder)
at Microsoft.AspNetCore.HostFilteringStartupFilter.<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder app)
at Microsoft.AspNetCore.Hosting.GenericWebHostService.<StartAsync>d__31.MoveNext()
This exception was originally thrown at this call stack:
CompoundAlertProcessor.Razor.Services.RazorViewToStringRenderer.FindView(Microsoft.AspNetCore.Mvc.ActionContext, string) in RazorViewToStringRenderer.cs
CompoundAlertProcessor.Razor.Services.RazorViewToStringRenderer.RenderViewToStringAsync<TModel>(string, TModel) in RazorViewToStringRenderer.cs
Inner Exception 1:
InvalidOperationException: Unable to find view '/Views/Emails/ConfirmAccount/ConfirmAccountEmail.cshtml'. The following locations were searched:
/Views/Emails/ConfirmAccount/ConfirmAccountEmail.cshtml
我一直在玩包和设置,试图弄清楚魔术 Sdk.Web
在做什么,Sdk.Worker
但我不知道。我知道 SDK 会在幕后加载和编排很多事情,以使您更容易实现所需的结果,但我找不到任何可以说明它实际在做什么的事情。
我担心尝试使用有基础的工人Sdk.Web
会有其他我现在无法预见的变化。像这样使用它是否安全?有什么办法让我只取我需要的碎片Sdk.Web
并将它们注入Sdk.Worker
?
我是否应该放弃使用完整的 Razor,而是尝试使用RazorLite 之类的东西,就像在 .net 标准 2.1 / Core 3.1 中描述的Razor 电子邮件模板一样?我总是对多年未更新的项目保持警惕。
解决方案
推荐阅读
- python - Python bz2 readlines slow in byte-mode
- linux - 如何均衡列块的长度
- flutter - Flutter TextSpan Gesture detection function
- c# - How can IDisposable field be null here?
- jquery - Laravel jQuery validation tow forms on different tow taps bootstrap in on page
- android - Firebase Cloud Messaging Java client
- javascript - Test class component firebase action with Jest
- javascript - 如何在网站中按位置更改光标样式
- java - 澄清日期输出
- r - 如何在R中形成两个数据集的矩阵?