3

我正在寻找一种将 MVC ActionResult 保存到字节数组(文件)的好方法。原因是我正在使用 Rotativa 将 HTML 视图转换为 PDF。这很好用,并在浏览器中用 PDF 返回我的用户。现在我想从服务器发送一封电子邮件,包括相同的 PDF 作为附件。为了发送电子邮件,我使用 ActionMailer.Net nuget 包。可以选择将字节数组作为附件。

所以我需要将一个字节数组与我的 PDF 文件一起传递给发送邮件方法。但是返回 PDF 的操作将 ActionResult 作为返回类型,而不是 FileStreamResult(不幸的是)。我不完全知道为什么会做出这个选择,但就是这样。

Rotativa 包使用 Wkhtmltopdf 来转换 HTML。我想我可以自己实现,但这似乎毫无意义,因为我已经有一个方法可以返回我需要的东西;我只需要一种方法将该结果转换为字节数组。

4

3 回答 3

6

您可以继承“ViewAsPdf”并创建一个方法来调用“ViewAsPdf”的一些受保护方法:

public class ViewAsPdf2 : ViewAsPdf
{
    public ViewAsPdf2(string viewName, object model) : base(viewName, model) { }
    public byte[] GetByte(ControllerContext context)
    {
        base.PrepareResponse(context.HttpContext.Response);
        base.ExecuteResult(context);
        return base.CallTheDriver(context);
    }
}

在你的行动中:

var pdf = new ViewAsPdf2("MyView", model);
var pdfByteArray = pdf.GetByte(ControllerContext);
SendEmail(pdfByteArray);
return null;

因此,您可以使用byte[]来做您想做的事情,返回的将是 PDF。

于 2014-08-18T17:15:42.513 回答
0

您可以向应该返回 PDF 并将结果保存为字节数组的控制器操作发送 HTTP 请求。这WebClient.DownloadData方法似乎合适。

如果要保留上下文(会话、已验证用户),则需要设置 Cookie 标头:

client.Headers[HttpRequestHeader.Cookie] = Request.Headers["Cookie"];
于 2012-11-15T11:49:20.343 回答
0

我有同样的问题,这是我的解决方案:

您基本上需要向您自己的 URL 发出 HTTP 请求并将输出保存为二进制文件。简单,没有重载,辅助类和臃肿的东西。

你需要这个方法:

    // Returns the results of fetching the requested HTML page.
    public static void SaveHttpResponseAsFile(string RequestUrl, string FilePath)
    {
        try
        {
            HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(RequestUrl);
            httpRequest.UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)";
            httpRequest.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate");
            HttpWebResponse response = null;
            try
            {
                response = (HttpWebResponse)httpRequest.GetResponse();
            }
            catch (System.Net.WebException ex)
            {
                if (ex.Status == WebExceptionStatus.ProtocolError)
                    response = (HttpWebResponse)ex.Response;
            }

            using (Stream responseStream = response.GetResponseStream())
            {
                Stream FinalStream = responseStream;
                if (response.ContentEncoding.ToLower().Contains("gzip"))
                    FinalStream = new GZipStream(FinalStream, CompressionMode.Decompress);
                else if (response.ContentEncoding.ToLower().Contains("deflate"))
                    FinalStream = new DeflateStream(FinalStream, CompressionMode.Decompress);

                using (var fileStream = System.IO.File.Create(FilePath))
                {
                    FinalStream.CopyTo(fileStream);
                }

                response.Close();
                FinalStream.Close();
            }
        }
        catch
        { }
    }

然后在您的控制器内部,您可以这样称呼它:

SaveHttpResponseAsFile("http://localhost:52515/Management/ViewPDFInvoice/" + ID.ToString(), "C:\\temp\\test.pdf");

还有哇!该文件在您的文件系统中,您可以双击并打开 PDF,或通过电子邮件将其发送给您的用户,或任何您需要的...

于 2013-03-03T01:39:48.533 回答