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 包。
我正在尝试使用 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 包。