1

I'm relatively new to MVC, so please let me know if i'm attacking this problem from the wrong angle.

I have several views I'd like to supply to the user in both html and pdf formats. Using the HiQPdf dll, this is a very easy task, so I am just trying to wrap up a helper function on my Controller base class so I can do something like:

public ActionResult MyAction(MyActionVM model) {

  if(Request.QueryString["type"] == "pdf") {
    return Pdf("ViewName", model, "htmlaspdf.pdf");
  }

  return View("ViewName");
}

This is what I've implemented so far, and it compiles just fine and appears to my naive self that it should work. When I run the action, however, it fails on the first line of the Pdf() function with the exception below which doesn't make a ton of sense to me. It's obviously calling a ViewContext ctor, but I'm not sure why or how to go about fixing it. Any insight?

public class CustomBaseController : Controller {
  protected FileResult Pdf(string viewname, object data, string filename) {
    HtmlToPdf converter = new HtmlToPdf(); //Exception stack references this line
    MemoryStream ms = new MemoryStream();

    using (var sw = new StringWriter()) {
      ViewResult view;
      if (String.IsNullOrWhiteSpace(viewname))
        view = this.View(data);
      else
        view = this.View(viewname, data);

      //roughly taken from the examples here: http://blog.janjonas.net/2011-06-18/aspnet-mvc3-controller-extension-method-render-partial-view-string
      var viewContext = new ViewContext(this.ControllerContext, view.View, ViewData, TempData, sw);
      view.View.Render(viewContext, sw);
      converter.ConvertHtmlToStream(sw.GetStringBuilder().ToString(), null, ms);
    }

    ms.Position = 0;

    return File(ms, "application/octet-stream", filename);
  }
}

Exception

[ArgumentNullException: Value cannot be null.
Parameter name: view]
   System.Web.Mvc.ViewContext..ctor(ControllerContext controllerContext, IView view, ViewDataDictionary viewData, TempDataDictionary tempData, TextWriter writer) +326
   MyNamespace.Utilities.MyNamespaceController.Pdf(String viewname, Object data, String filename) in G:\brendans\Projects\MyNamespace\MyNamespace\Utilities\MyNamespaceController.cs:21
BLSully
  • 5,929
  • 1
  • 27
  • 43
  • 1
    The exception points to the second argument `view.View` of the ViewContext constructor. You are just creating `view` as a ViewResult but you are never actually rendering the view. See [this answer](http://stackoverflow.com/a/2759898/1836935) about how to render a view into a string – Daniel J.G. Sep 17 '15 at 15:59
  • Alright, well that worked perfectly. Thanks much – BLSully Sep 17 '15 at 17:02

1 Answers1

0

Thanks to Daniel J.G. This slight modification worked perfectly.

  MemoryStream ms = new MemoryStream();
  HtmlToPdf converter = new HtmlToPdf();

  ViewData.Model = model;

  using (var sw = new StringWriter()) {
    var viewengineresult = ViewEngines.Engines.FindPartialView(this.ControllerContext, viewname);
    var viewcontext = new ViewContext(this.ControllerContext, viewengineresult.View, ViewData, TempData, sw);
    viewengineresult.View.Render(viewcontext, sw);
    converter.ConvertHtmlToStream(sw.GetStringBuilder().ToString(), null, ms);
  }

  ms.Position = 0;

  return File(ms, "application/octet-stream", filename);
BLSully
  • 5,929
  • 1
  • 27
  • 43