Rotativa.aspnetcore 中的 BuildFile 错误

Tan*_*wer 4 c# rotativa asp.net-core asp.net-core-2.0

在 asp.net core 2.1 应用程序中使用旋转将视图转换为 pdf 时会出现错误

值不能为空。参数名称:path1

下面是我的代码

var rpt = new ViewAsPdf();
            //rptLandscape.Model = Model;
            rpt.PageOrientation = Rotativa.AspNetCore.Options.Orientation.Landscape;
            rpt.PageSize = Rotativa.AspNetCore.Options.Size.A4;
            rpt.ViewName = "Test";
            byte[] arr = await rpt.BuildFile(actionContextAccessor.ActionContext);
            System.IO.File.WriteAllBytes(Path.Combine(env.WebRootPath, "PDFStorage", "File.pdf"), arr);
Run Code Online (Sandbox Code Playgroud)

虽然它成功地将网页返回为 pdf,但我想将它存储在一个文件夹中。此错误的可能原因是什么?,我已经检查了所有,它甚至不包含名称 name1 的属性

更新 1:错误不在 Path.Combine() 中,错误在它之前。

byte[] arr = await rpt.BuildFile(actionContextAccessor.ActionContext);
Run Code Online (Sandbox Code Playgroud)

Pan*_*vos 6

精简版

你需要调用RotativaConfiguration.Setup(env);Startup.cs 下载和部署另一个工具做实际的转换工作。您可能应该找到一个不同的库。

长版

如果没有实际的异常及其调用堆栈,人们只能猜测,或者检查源代码并尝试猜测可能出错的地方。

BuildFile 的源代码是:

   public async Task<byte[]> BuildFile(ActionContext context)
    {
        if (context == null)
            throw new ArgumentNullException("context");

        //if (this.WkhtmlPath == string.Empty)
        //    this.WkhtmlPath = context.HttpContext.Server.MapPath("~/Rotativa");

        this.WkhtmlPath = RotativaConfiguration.RotativaPath;

        var fileContent = await CallTheDriver(context);

        if (string.IsNullOrEmpty(this.SaveOnServerPath) == false)
        {
            File.WriteAllBytes(this.SaveOnServerPath, fileContent);
        }

        return fileContent;
    }
Run Code Online (Sandbox Code Playgroud)

WriteAllBytes不可能是罪魁祸首。不过,它确实WkhtmlPathRotativaConfiguration.RotativaPath设置设置了属性。内部调用CallTheDriver()表明该库仅调用带有一些开关的可执行文件来转换 PDF 文件。

执行 exe的实际调用,从ViewAsPdf.csto 开始WkhtmlDriver.cs是:

        var proc = new Process
        {
            StartInfo = new ProcessStartInfo
            {
                FileName = Path.Combine(wkhtmlPath, wkhtmlExe),
                Arguments = switches,
                UseShellExecute = false,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                RedirectStandardInput = true,
                WorkingDirectory = wkhtmlPath,
                CreateNoWindow = true
            }
        };
        proc.Start();
Run Code Online (Sandbox Code Playgroud)

如果wkhtmlPath为空,您将得到空参数异常。所有这些调用都会出现在异常的调用堆栈中。

解决方案是确保RotativaConfiguration.RotativaPath正确设置该属性。回购本身解释说

在 Startup.cs 中完成的基本配置:

RotativaConfiguration.Setup(env);
Run Code Online (Sandbox Code Playgroud)

确保您有一个文件夹,其中包含可由运行 Web 应用程序的进程访问的 wkhtmltopdf.exe 文件。默认情况下,它会在 Web 应用程序根目录中名为“Rotativa”的文件夹中搜索。如果您需要使用可选参数更改设置调用 RotativaConfiguration.Setup(env, "path/relative/to/root")

顺便说一句,该库的作用是,在Web 应用程序中运行单独的可执行文件是一个非常非常糟糕的主意:

  1. 失去了可扩展性。为每个请求运行一个单独的可执行文件非常昂贵,并且很容易淹没繁忙的服务器。这就是生产服务器不能以这种方式工作的原因。如果进程挂起,请求会被处理。您最终可能会遇到孤立的进程。
  2. 其次,它需要提升的权限- Web应用程序的帐户必须能够执行任意可执行文件,它的东西应该不会被允许做。

最后,忘记跨平台部署。尽管https://wkhtmltopdf.org/站点提供了适用于所有操作系统的版本,但可执行文件名称被硬编码为“wkhtmltopdf.exe” 。

顺便说一句,该工具本身提供了一个用于其他应用程序的 C 库