1

我有以下

  • dotnet core 6 控制台应用程序
  • dotnet core 6 Razor 类库(带有 .cshtml)

我正在做一个在 web api 中工作得很好的 View Engine RenderAsync()。在控制台应用程序中运行时找不到模板,模板在 dll 中。

在此处输入图像描述

第一个问题,该cshtml的相对/绝对路径是什么?我正在使用:@"Templates/Pdf/LevelsEmail.cshtml"

控制台应用启动

IServiceCollection serviceCollection = new ServiceCollection();
services.AddScoped<ITemplateBuilder, TemplateBuilder>();
var listener = new DiagnosticListener("Microsoft.AspNetCore");
services.AddSingleton(listener);
services.AddSingleton<DiagnosticSource>(listener);
services.AddRazorPages();
// rest of deps
var scope = provider.CreateScope();
await scope.ServiceProvider.GetRequiredService<Runner>().ProcessAsync();

在 RCL csproj

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

    <PropertyGroup>
        <TargetFramework>net6.0</TargetFramework>
        <AddRazorSupportForMvc>true</AddRazorSupportForMvc>
    </PropertyGroup>
    
    <ItemGroup>
        <FrameworkReference Include="Microsoft.AspNetCore.App" />
    </ItemGroup>

</Project>

尝试 GetView 或 FindView

var httpContext = new DefaultHttpContext
        {
            RequestServices = _serviceProvider
        };
    var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());

搜索 ViewEngineResult

    var viewResult = _viewEngine.GetView(executingFilePath: viewPath, viewPath: viewPath, isMainPage);
    if (getViewResult.Success)
    {
        return getViewResult;
    }

    var findViewResult = _viewEngine.FindView(actionContext, viewPath, isMainPage);
    if (findViewResult.Success)
    {
        return findViewResult;
    }

然后渲染(这只是一个例子,问题在于获取视图)

var viewContext = new ViewContext(actionContext, 
                        viewResult.View, 
                        viewDictionary,
                        new TempDataDictionary(httpContext, _tempDataProvider), 
                        outputWriter, 
                        new HtmlHelperOptions());
      await viewResult.View.RenderAsync(viewContext);

第二个问题:这可以在控制台应用程序(而不是网络应用程序)中使用 RazorViewEngine 吗?

4

1 回答 1

1

找到了一种解决方法,它不是问题的答案,所以我会保持打开状态,但它对我有用。

所以:

将控制台应用程序更改为 Web

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

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

程序看起来像:

var builder = WebApplication.CreateBuilder();
builder.Configuration.AddJsonFile("appsettings.json", optional: true);

builder.Services.AddModules(builder.Configuration);

var app = builder.Build();

ITemplateService myBuilder = app.Services.GetRequiredService<ITemplateBuilder>();

MyModel email = new MyModel{ Data = InitData() };

string compiled = await myBuilder.RenderAsync(MyModel.Template, email, true);

强制收集服务

.AddRazorPages();

控制台应用程序 DiagnosticListener 和 DiagnosticSource 中所需的其余依赖项不再需要显式注入,Web 项目会处理这些。

对我来说这是一个很好的解决方案,因为这个控制台应用程序在 docker 容器中运行,我没有测试它是否可以在持久的 azure 函数或 aws lambda 函数中运行,我感觉不是,但必须进行测试。

于 2022-01-19T19:15:07.183 回答