我正在为ASP.NET应用程序开发增强功能,该功能允许用户通过电子邮件将屏幕渲染的PDF附件发送到指定的分发。尽管发送电子邮件成功,但这似乎使应用程序感到困惑,并且随后的页面刷新失败,并显示HttpException:“无法使用前导..退出顶层目录。”这是刷新失败的唯一情况。
页面遵循以下继承模式:
Webform_HS_Proforma : Webform_ProformaBase { }
Webform_ProformaBase : System.Web.UI.Page { }
我们正在使用的PDF库是SelectPdf
,但是该库似乎不太可能出现问题,因为我们能够正确发送附件,也可以将PDF成功地写入数据库。
Request.Url.PathAndQuery
显示正确的预期路径,并且项目中没有包含“ .. \”的引用。在子类和父类中都在调用base.Render
之前检查此选项。
各个页面位于文件夹Pages中。将site.master
移到该位置无济于事。
有一个Global.asax
,它的存在与否不影响此结果。
冒犯性的方法似乎是ShowRender
,包含在Webform_ProformaBase
类中,结合了将文件附加到电子邮件的动作。我通过谨慎使用评论得出了这个结论。尽管如此,ShowRender
仍在不同的函数中工作,无一例外将返回结果写入数据库。此处的区别在于我们没有将其附加到电子邮件中。
我试图将ShowRender
从Webform_ProformaBase
移到Webform_HS_Proforma
并遇到相同的异常。
此方法执行电子邮件和附件的创建,并将其发送。该方法成功完成。
protected void OnEmailResolvedInvoked(String fromAddress = null, String toAddress = null, String ccAddress = null, String msgSubject = null, String msgBody = null)
{
// The user control that kicks off the process by collecting the
// information passed in params. Hide the panel once its job is
// done. Make the main page visible again.
panelEmailCtrl.Visible = false;
panelBody.Visible = true;
if (toAddress is null || fromAddress is null)
{
return;
}
// Let's send this email.
StringWriter tw = new StringWriter();
HtmlTextWriter hw = new HtmlTextWriter(tw);
MailMessage message = new MailMessage();
message.IsBodyHtml = true;
message.From = new MailAddress(fromAddress.Trim());
message.To.Add(toAddress.Trim());
if (ccAddress.Length > 0)
{
message.CC.Add(new MailAddress(ccAddress.Trim()));
}
message.Subject = msgSubject;
SelectPdf.PdfDocument doc = this.ShowRender();
// Adds the proforma PDF as an attachment to the email.
byte[] bytes = doc.Save();
message.Attachments.Add(new Attachment(new MemoryStream(bytes), tbProFormaName.Text + " Proforma " + DateTime.Now.ToShortDateString() + ".pdf"));
// Close any remaining references here.
doc?.Close();
hw?.Close();
tw?.Close();
SmtpClient client = new SmtpClient();
try
{
client.Send(message);
}
catch (SmtpException) { /* Error handling here. */ }
catch (Exception) { /* Error handling here. */ }
}
这是ShowRender
方法。该文档将在OnEmailResolvedInvoked
中传递回调用方,而不会发生意外。
public PdfDocument ShowRender()
{
TextWriter preWriter = new StringWriter();
HtmlTextWriter htmlWriter = new HtmlTextWriter(preWriter);
this.Render(htmlWriter);
HtmlToPdf converter = new HtmlToPdf();
// Options for presentation.
converter.Options.PdfPageSize = PdfPageSize.Legal;
converter.Options.PdfPageOrientation = PdfPageOrientation.Portrait;
converter.Options.MarginLeft = 10;
converter.Options.MarginRight = 10;
converter.Options.MarginTop = 20;
converter.Options.MarginBottom = 20;
PdfDocument doc = converter.ConvertHtmlString(preWriter.ToString(), Request.Url.AbsoluteUri);
preWriter?.Close();
htmlWriter?.Close();
return doc;
}
成功完成此操作后,页面将尝试回发。 Webform_HS_Proforma
的Render方法是有条件的,但是此方法转到仅调用base.Render
的分支。 Webform_ProformaBase
中引发了异常。
在一天结束时,重定向可能会导致用户丢失当前输入的任何数据。我很茫然。似乎没有任何理由使失败。
[HttpException (0x80004005): Cannot use a leading .. to exit above the top directory.]
System.Web.Util.UrlPath.ReduceVirtualPath(String path) +769
System.Web.Util.UrlPath.Reduce(String path) +82
System.Web.Util.UrlPath.Combine(String appPath, String basepath, String relative) +299
System.Web.UI.Control.ResolveClientUrl(String relativeUrl) +377
System.Web.UI.HtmlControls.HtmlLink.RenderAttributes(HtmlTextWriter writer) +74
System.Web.UI.HtmlControls.HtmlLink.Render(HtmlTextWriter writer) +41
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +128
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +287
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +27
System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +197
System.Web.UI.HtmlControls.HtmlHead.RenderChildren(HtmlTextWriter writer) +21
System.Web.UI.HtmlControls.HtmlContainerControl.Render(HtmlTextWriter writer) +32
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +128
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +287
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +27
System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +197
System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +9
System.Web.UI.Control.Render(HtmlTextWriter writer) +10
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +128
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +287
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +27
System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +197
System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +9
System.Web.UI.Page.Render(HtmlTextWriter writer) +30
ProformaBuilder.Pages.WebForm_ProformaBase.Render(HtmlTextWriter writer) in C:\[Structure]\Pages\WebForm_ProformaBase.aspx.cs:290
ProformaBuilder.Pages.WebForm_HS_Proforma.Render(HtmlTextWriter writer) in C:\[Structure]\Pages\WebForm_HS_Proforma.aspx.cs:813
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +128
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +287
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +27
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5625