MVC5在Base Controller类上实现自定义FileResult函数

时间:2015-09-17 15:18:10

标签: c# asp.net-mvc asp.net-mvc-controller

我对MVC比较新,所以如果我从错误的角度攻击这个问题,请告诉我。

我有几种观点,我想以html和pdf格式提供给用户。使用HiQPdf dll,这是一个非常简单的任务,所以我只是想在我的Controller基类上包装一个辅助函数,所以我可以做类似的事情:

public ActionResult MyAction(MyActionVM model) {

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

  return View("ViewName");
}

这是我到目前为止所执行的内容,它编译得很好,并且在我天真的自我看来它应该有效。但是,当我运行动作时,它会在Pdf()函数的第一行失败,但下面的例外情况对我来说并没有多大意义。它显然是在调用ViewContext ctor,但我不确定为什么或如何修复它。有什么见解吗?

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

异常

[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

1 个答案:

答案 0 :(得分:0)

感谢Daniel J.G.这种轻微的修改非常有效。

  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);
相关问题