我不知道为什么 Server.Execute 会引发异常,但这是使用该调用的替代方法。
您正在使用 Server.Execute 将网页转换为 HTML。Winnovative 没有采用这种方法。诀窍是允许该页面请求访问当前用户的会话。您指定要调用的 URL,然后在 PDFConverter 的 cookie 集合中提供用户凭据。
请参阅此页面并根据您的身份验证技术选择方法。
Winnovative 身份验证处理
编辑:
@LordHonydew,我们在评论中绕了一个大圈,并在一开始就结束了。让我再试一次。
首先,在 Server.Execute 异常中是否存在内部异常?可能有更多信息有助于解释问题所在。即使在解决了该问题之后,还有其他项目必须修复。
其次,当使用 Winnovative 从受保护的网页生成 PDF 时,您必须向 PDFConverter 提供凭据,以便它可以访问该页面及其资源。winnovative 可以通过多种方式获取 HTML:一种是通过为 PDFConverter 提供要调用的 URL,另一种是使用 Server.Execute 直接获取 HTML,然后为 PDFConverter 提供 HTML,这就是您的方式正在做。无论哪种方式,PDFConverter 仍然需要与服务器通信以获取额外的页面资源。像图像和 CSS 文件这样的东西不在 HTML 中,它们被 HTML 引用。转换器将调用服务器以获取这些项目。由于您的应用程序是安全的,您必须向转换器提供访问服务器的凭据。我们将通过使用用于每个页面请求的相同身份验证 cookie 来做到这一点。还有其他方法,例如提供用户名和密码。上面的链接解释了各种方式。
此代码从当前请求中获取 auth cookie 并将其提供给转换器:
pdfConverter.HttpRequestCookies.Add(FormsAuthentication.FormsCookieName,
Request.Cookies[FormsAuthentication.FormsCookieName].Value);
最后,converter.SavePdfFromUrlToFile 不是正确的使用方法。那只会将收据保存到本地服务器的驱动器中。您需要将其流式传输回给用户。
试试下面的。在 catch 块中设置断点,以便查看是否存在内部异常。
protected void Save_BtnClick(object sender, EventArgs e)
{
// Get the web page HTML as a string
string htmlCodeToConvert = null;
using (StringWriter sw = new StringWriter())
{
try
{
System.Web.HttpContext.Current.Server.Execute("Receipt.aspx", sw);
htmlCodeToConvert = sw.ToString();
}
catch (Exception ex)
{
// set breakpoint below and on an exception see if there is an inner exception.
throw;
}
}
PdfConverter converter = new PdfConverter();
// Supply auth cookie to converter
converter.HttpRequestCookies.Add(System.Web.Security.FormsAuthentication.FormsCookieName,
Request.Cookies[System.Web.Security.FormsAuthentication.FormsCookieName].Value);
// baseurl is used by converter when it gets CSS and image files
string baseUrl = Request.Url.Scheme + "://" + Request.Url.Authority +
Request.ApplicationPath.TrimEnd('/') + "/";
// create the PDF and get as bytes
byte[] pdfBytes = converter.GetPdfBytesFromHtmlString(htmlCodeToConvert, baseUrl);
// Stream bytes to user
Response.Clear();
Response.AppendHeader("Content-Disposition", "attachment;filename=Receipt.pdf");
Response.ContentType = "application/pdf";
Response.OutputStream.Write(pdfBytes, 0, pdfBytes.Length);
HttpContext.Current.ApplicationInstance.CompleteRequest();
}