Rotativa Value不能为null。参数名称:context

问题描述 投票:0回答:1

我试图使用Rotativa生成PDF并返回字节,但是我收到错误:

值不能为空。参数名称: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;
}

返回的值是Value不能为null。参数名称:context

我究竟做错了什么?

c# asp.net rotativa
1个回答
0
投票

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

如果您需要像示例中那样手动创建控制器,则必须自己创建上下文。 Derek Comartin在他的博客文章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包。

© www.soinside.com 2019 - 2024. All rights reserved.