Reputation: 884
I'm using Rotativa to generate PDFs from actions/views and it works great. However is it possible to use it inside of models or can you purely use it in controllers?
The issue is that the function wants to use a ControllerContext which models doesn't have
var pdfResult = new ActionAsPdf("GeneratePDF", "PDF");
byte[] pdfFile = pdfResult.BuildPdf(this.ControllerContext);
My end result is that I want the PDF in a byte array if there are other ways of doing it
Upvotes: 4
Views: 4585
Reputation: 1778
You can use the following code to instantiate controllers and then configure a ControllerContext through that instance - from anywhere in your application.
/// <summary>
/// Creates an instance of an MVC controller from scratch
/// when no existing ControllerContext is present
/// </summary>
/// <typeparam name="T">Type of the controller to create</typeparam>
/// <returns>Controller Context for T</returns>
/// <exception cref="InvalidOperationException">thrown if HttpContext not available</exception>
public static T CreateController<T>(RouteData routeData = null)
where T : Controller, new()
{
// create a disconnected controller instance
T controller = new T();
// get context wrapper from HttpContext if available
HttpContextBase wrapper = null;
if (HttpContext.Current != null)
wrapper = new HttpContextWrapper(System.Web.HttpContext.Current);
else
throw new InvalidOperationException(
"Can't create Controller Context if no active HttpContext instance is available.");
if (routeData == null)
routeData = new RouteData();
// add the controller routing if not existing
if (!routeData.Values.ContainsKey("controller") && !routeData.Values.ContainsKey("Controller"))
routeData.Values.Add("controller", controller.GetType().Name
.ToLower()
.Replace("controller", ""));
controller.ControllerContext = new ControllerContext(wrapper, routeData, controller);
return controller;
}
This can be used like:
QuotesController quotesController = ViewRenderer.CreateController<QuotesController>();
ViewAsPdf view = (ViewAsPdf)quotesController.Preview(model.Guid);
byte[] pdf = view.BuildPdf(quotesController.ControllerContext);
EmailService.Send(model, pdf);
Upvotes: 4