BuildFile Error In Rotativa.aspnetcore

纵然是瞬间 提交于 2020-05-13 05:38:50

问题


While converting a view as pdf in asp.net core 2.1 app with rotative it gives an error

Value cannot be null. Parameter name: path1

Below is my Code

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);

Although it returns webpage as pdf successfully, but I want to store it inside a folder. What are the possible reasons for this Error? , I have checked all, it does not even contain property by the name name1

Update 1: Error is not in Path.Combine(), the error is in line before it.

byte[] arr = await rpt.BuildFile(actionContextAccessor.ActionContext);

回答1:


Short Version

You need to call RotativaConfiguration.Setup(env); in Startup.cs and download and deploy another tool to do the actual conversion work. You should probably find a different library.

Long version

Without the actual exception and its call stack one can only guess, or check the source code and try to guess what could go wrong.

The source code for BuildFile is :

   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;
    }

WriteAllBytes can't be the culprit. It does set the WkhtmlPath property from the RotativaConfiguration.RotativaPath setting though. Following the calls inside CallTheDriver() shows that this library just calls an executable with some switches to convert the PDF file.

The actual call that executes the exe, traced from ViewAsPdf.cs to WkhtmlDriver.cs is :

        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();

If wkhtmlPath is null, you'll get a null argument exception. All those calls would appear in the exception's call stack.

The solution is to ensure that the RotativaConfiguration.RotativaPath property is set correctly. The repo itself explains that :

Basic configuration done in Startup.cs:

RotativaConfiguration.Setup(env);

Make sure you have a folder with the wkhtmltopdf.exe file accessible by the process running the web app. By default it searches in a folder named "Rotativa" in the root of the web app. If you need to change that use the optional parameter to the Setup call RotativaConfiguration.Setup(env, "path/relative/to/root")

BTW what that library does, run a separate executable in a web application is a very, very bad idea:

  1. Scalability is lost. Running a separate executable for each request is very expensive and can easily flood a busy server. That's why production servers don't work this way. If the process hangs, the request hands. You can end up with orphaned processes.
  2. Second, it requires elevated permissions - the web app's account has to be able to execute arbitrary executables, something it should not be allowed to do.

Finally, forget about cross-platform deployment. The executable name is hard-coded to "wkhtmltopdf.exe", even though the https://wkhtmltopdf.org/ site provides versions for all OSs.

BTW the tool itself provides a C library for use in other applications




回答2:


Path.Combine throws an ArgumentNullException if one of the input strings is null.

env.WebRootPath is null, make sure it's initialized with a value.


Source of Path.Combine:

public static String Combine(String path1, String path2, String path3) {
    if (path1 == null || path2 == null || path3 == null)
        throw new ArgumentNullException((path1 == null) ? "path1" : (path2 == null) ? "path2" : "path3");
    Contract.EndContractBlock();
    CheckInvalidPathChars(path1);
    CheckInvalidPathChars(path2);
    CheckInvalidPathChars(path3);

    return CombineNoChecks(CombineNoChecks(path1, path2), path3);
}


来源:https://stackoverflow.com/questions/51513393/buildfile-error-in-rotativa-aspnetcore

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!