我正在寻找一种将MVC ActionResult保存到字节数组(文件)的好方法。原因是我使用Rotativa将HTML视图转换为PDF。这很好用,并在浏览器中返回我的用户PDF。现在我想从服务器发送一封电子邮件,包括与附件相同的PDF。对于发送电子邮件,我使用的是ActionMailer.Net nuget包。这可以选择包含字节数组作为附件。
所以我需要将带有PDF文件的字节数组传递给send mail方法。但是返回PDF的操作将ActionResult作为返回类型,而不是FileStreamResult(不幸的是)。我不知道为什么会做出这样的选择,但事实就是如此。
Rotativa包使用Wkhtmltopdf转换HTML。我想我可以自己实现,但这似乎有点无意义,因为我已经有一个方法可以返回我需要的东西;我只需要一种方法将结果转换为字节数组。
答案 0 :(得分: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。
答案 1 :(得分:0)
您可以向应该返回PDF的控制器操作发送HTTP请求,并将结果保存为字节数组。 WebClient.DownloadData
方法似乎合适。
如果要保留上下文(会话,经过身份验证的用户),则需要设置Cookie标头:
client.Headers[HttpRequestHeader.Cookie] = Request.Headers["Cookie"];
答案 2 :(得分: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");
和wala!该文件位于您的文件系统上,您可以双击并打开PDF,或通过电子邮件发送给您的用户,或者您需要的任何内容......