c# - 创建和发送 Smtp 附件后渲染时出现 System.Web.HttpException
问题描述
我正在为 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
to移动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
解决方案
推荐阅读
- javascript - 在客户端 js 文件中使用 pug 变量
- html - 相对线高不向下级联到
- java - 如何使用java连接spark数据框中的所有列?
- c# - 在while循环和!Console.KeyAvailable C#中嵌套开关/案例
- html - 选中复选框后不应用复选框边框
- javascript - 暂停 chart.js 水平滚动
- postgresql - Postgresql 自动清理耗时过长
- ios - 字符串中日期的可访问性语音一
- laravel - Laravel 7 无法解析的依赖解析 - 刀片组件
- flutter - 在flutter中按钮的onPressed回调中调用flutterTts.setStartHandler()方法是一个好习惯吗?(flutter_tts插件)