Rotativa 值不能为空。参数名称:上下文

Rotativa Value cannot be null. Parameter name: context

我正在尝试使用 Rotativa 生成 PDF 和 return 个字节,但是我收到错误:

Value cannot be null. Parameter name: context

这是我的代码:

public string getReportsPDF(string community, string procedure)
{
    SiteSuperReportsController controller = new SiteSuperReportsController();

    string value = "";
    byte[] pdfBytes = new byte[] { };

    if (procedure == "GetProductionTasks")
    {
        var actionPDF = new Rotativa.ActionAsPdf("RedBluePDF", new { community = community, procedure = procedure })
        {
            PageSize = Size.A4,
            PageOrientation = Rotativa.Options.Orientation.Landscape,
            PageMargins = { Left = 1, Right = 1 }
        };
        try
        {
            pdfBytes = actionPDF.BuildFile(controller.ControllerContext);
            value = "Works";
        }
        catch(Exception e)
        {
            value = e.Message.ToString();
        }
    }
    return value;
}

值 returned 是值不能为空。参数名称:context

我做错了什么?

一个选项是将对 BuildFile 的调用移动到控制器的操作方法中,其中控制器上下文可用 属性 调用 ControllerContext

如果您需要像示例中那样手动创建控制器,则必须自己创建上下文。 Derek Comartin 在他的博客 post Using Razor in a Console Application (outside of ASP.NET Core MVC) 中展示了如何为 ASP.Core 2 项目执行此操作。对于您的情况,请尝试更改

pdfBytes = actionPDF.BuildFile(controller.ControllerContext);

pdfBytes = actionPDF.BuildFile(CreateDummyControllerContext("SiteSuperReports"));

使用以下方法:

    private ControllerContext CreateDummyControllerContext(string controllerName)
    {
        var context = new ControllerContext
        {
            HttpContext = new DefaultHttpContext
            {
                RequestServices = GetServiceProvider()
            },
            RouteData = new RouteData
            {
                Values = {{"controller", controllerName}}
            },
            ActionDescriptor = new Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor
            {
                RouteValues = new Dictionary<string, string>(),
            }
        };

        return context;
    }

    // see https://codeopinion.com/using-razor-in-a-console-application/
    private ServiceProvider GetServiceProvider()
    {
        var services = new ServiceCollection();
        services.AddSingleton(PlatformServices.Default.Application);
        var environment = new HostingEnvironment
        {
            ApplicationName = Assembly.GetEntryAssembly().GetName().Name
        };
        services.AddSingleton<IHostingEnvironment>(environment);
        services.Configure<RazorViewEngineOptions>(options =>
        {
            options.FileProviders.Clear();
            options.FileProviders.Add(new PhysicalFileProvider(Directory.GetCurrentDirectory()));
        });
        services.AddSingleton<ObjectPoolProvider, DefaultObjectPoolProvider>();
        services.AddSingleton<DiagnosticSource>(new DiagnosticListener("Microsoft.AspNetCore"));

        services.AddLogging();
        services.AddMvc();

        return services.BuildServiceProvider();
    }

您可能需要添加 Microsoft.Extensions.PlatformAbstractions 包。