I'm working on enhancement functionality for an ASP.NET application that allows the user to send a PDF attachment of a screen render via email to a specified distribution. Although sending the email succeeds, this seems to confuse the application and the subsequent page refresh fails with an HttpException: "Cannot use a leading .. to exit above the top directory." This is the only situation in which a refresh fails.
The page follows this inheritance pattern:
Webform_HS_Proforma : Webform_ProformaBase { }
Webform_ProformaBase : System.Web.UI.Page { }
The PDF library we're using is SelectPdf
, but it seems unlikely that this library is a problem, since we're able to send the attachment correctly and also to elsewhere successfully write the PDF to a database.
Request.Url.PathAndQuery
show the correct intended path and there are no references in the project that include "..\". This is checked prior to the call to base.Render
in both the child-class and the parent-class.
The individual pages are located inside a folder, Pages. Moving the site.master
to this location does not help.
There is a Global.asax
, the presence or absence of which does not affect this outcome.
The offending method appears to be ShowRender
, contained in the Webform_ProformaBase
class combined with the act of attaching the file to an email. I reached this conclusion by judicious use of commenting. Nonetheless, ShowRender
works in a different function without exception that writes the return-product to the database. The difference here is that we're not attaching it to an email.
I tried to move ShowRender
from Webform_ProformaBase
to Webform_HS_Proforma
and got the same exception.
This method carries out the creation of the email and attachment, and sends it. This method completes successfully.
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. */ }
}
This is the ShowRender
method. The document is passed back to the caller in OnEmailResolvedInvoked
without incident.
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;
}
Once we've successfully completed this, the page will attempt to post-back. Webform_HS_Proforma
's Render method is a conditional, but this method goes to a branch that only calls base.Render
. The exception is thrown in Webform_ProformaBase
.
At the end of the day, a redirect could cause users to lose any data currently input. I'm at a loss. There seems to be no reason why this is failing.
[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
User contributions licensed under CC BY-SA 3.0