ASP .NET 2.0 Application Page not working from Subfolder


I've developed a nice VB supported website using a site.master that I am developing some content management system functions (e.g., uploading images to image folder, documents to document folder, editing web pages).  All of my functions work when they are stored in the main website folder (i.e., /main/). I've also modified the web.config so that the pages are only available to authenticated users. I have also set up restrictions so that the editor pages can not be edited using the editing tools.  All of this editing will happen on a staging server (as manual edits are completed now), then will be copied over by another person to the live (public) server.

Since the person moving the files live, is not the same person doing the development, I would like to keep all of the editing files in one folder (e.g., /main/cms/) that will not be copied to the live server.   When I put my files into the /cms/ folder, I run into errors. More specifically, the files will read from other directories (e.g., /main/images), but when I try to upload or delete a file, I get the custom error page I developed and am re-directed to the default page.  

When I look at the the error line in the URL from the error page re-direct, it appears that the file is trying to submit from the main folder location. For example, when trying to delete an image using my images.aspx file in cms (i.e., /main/cms/images.aspx), it appears as if the "action" does not account for the "cms."

I've added the site.master to the cms folder and referenced correctly, with the same result.  I am wondering if I need to somehow re-write the action statement or how to resolve this issue.  I tried to add a C# script in the app_folder as my latest resort, but haven't had any luck referencing it correctly in the page.  I'm not even sure that that is the correct solution and I am stuck.
Who is Participating?
atljarmanAuthor Commented:
Here is how to solve this:

Add the following --> actionscript.vb to the App_Folder (code attached)

Reference the class in the top of you page as such: <%@ Import Namespace="testaction" %>

In your script, use this code to replace the action to the correct folder.  

        Me.Response.Filter = New cdsnetFormActionModifier(Me.Response.Filter, "cms\_advfileeditor.aspx")

The example here is the _advfileeditor.aspx in the cms in relation to the site.master that is at the root or base folder.
'actionscript.vb to the App_Folder

Imports System.Data
Imports System.Configuration
Imports System.Web
Imports System.Web.Security
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.WebControls.WebParts
Imports System.Web.UI.HtmlControls
Imports System.IO
Imports System.Text.RegularExpressions

Namespace testaction
	Public Class cdsnetFormActionModifier
		Inherits Stream
		Private _sink As Stream
		Private _position As Long
		Private _url As String
		Public Sub New(sink As Stream, url As String)
			_sink = sink
			_url = "$1" & url & "$3"
		End Sub
		Public Overrides ReadOnly Property CanRead() As Boolean
				Return True
			End Get
		End Property

		Public Overrides ReadOnly Property CanSeek() As Boolean
				Return True
			End Get
		End Property

		Public Overrides ReadOnly Property CanWrite() As Boolean
				Return True
			End Get
		End Property

		Public Overrides ReadOnly Property Length() As Long
				Return 0
			End Get
		End Property

		Public Overrides Property Position() As Long
				Return _position
			End Get
				_position = value
			End Set
		End Property

		Public Overrides Function Seek(offset As Long, direction As System.IO.SeekOrigin) As Long
			Return _sink.Seek(offset, direction)
		End Function

		Public Overrides Sub SetLength(length As Long)
		End Sub

		Public Overrides Sub Close()
		End Sub

		Public Overrides Sub Flush()
		End Sub

		Public Overrides Function Read(buffer As Byte(), offset As Integer, count As Integer) As Integer
			Return _sink.Read(buffer, offset, count)
		End Function

		Public Overrides Sub Write(buffer As Byte(), offset As Integer, count As Integer)
			Dim s As String = System.Text.UTF8Encoding.UTF8.GetString(buffer, offset, count)
			Dim reg As New Regex("(<form.*action="")([^""]*)" & "(""[^>]*>)", RegexOptions.IgnoreCase)
			Dim m As Match = reg.Match(s)
			If m.Success Then
				Dim form As String = reg.Replace(m.Value, _url)
				Dim iform As Integer = m.Index
				Dim lform As Integer = m.Length
				s = s.Substring(0, iform) & form & s.Substring(iform + lform)
			End If
			Dim yaz As Byte() = System.Text.UTF8Encoding.UTF8.GetBytes(s)
			_sink.Write(yaz, 0, yaz.Length)
		End Sub
	End Class
End Namespace

Open in new window

Could you post any code you use to save the files in it's directories?
atljarmanAuthor Commented:
I meant to upload one of the files previously.  In this attachment, I've uploaded the two files.  The first one displays the contents of the document folder.  If the user clicks on the document name, it displays the document.  If the user clicks on delete, it will delete when the file is in the main folder but not in the cms (i.e., sub folder).  The second, is the file to upload documents to the document folder.  Again, this will work from the main folder, but not from the sub folder.
'This is the page code to view documents in the document folder.

<%@ Page Language='VB' MasterPageFile='site.master' Title='Content Page for documents.aspx' %>

<%@ Import Namespace="System.IO" %>
<script runat='server'>
  Sub Page_Load(sender as Object, e as EventArgs)
    If Not Page.IsPostBack then
	Dim dirInfo As New DirectoryInfo(Server.MapPath("~\documents\"))

'      Dim dirInfo as New DirectoryInfo(Server.MapPath("."))

'articleList.DataSource = dirInfo.GetFiles("*.aspx")
        articleList.DataSource = dirInfo.GetFiles("*.*")
    End If
  End Sub
   Sub articleList_ItemDataBound(ByVal sender As Object, ByVal e As DataGridItemEventArgs)
    ' First, make sure we're NOT dealing with a Header or Footer row
     If e.Item.ItemType <> ListItemType.Header And _
        e.Item.ItemType <> ListItemType.Footer Then
        'Now, reference the Button control that the Delete ButtonColumn 
        'has been rendered to
         Dim deleteButton As Button = e.Item.Cells(0).Controls(0)

         'We can now add the onclick event handler
         deleteButton.Attributes("onclick") = "javascript:return " & _
         "confirm('Are you sure you want to delete the file " & _
         DataBinder.Eval(e.Item.DataItem, "Name") & "?')"
     End If
   End Sub
  Sub articleList_DeleteFile(ByVal sender As Object, ByVal e As DataGridCommandEventArgs)
     'First, get the filename to delete
      Dim fileName As String = articleList.DataKeys(e.Item.ItemIndex)

      lblMessage.Text = "You opted to delete the file " & fileName & ".<br /><br />"


      'You would want to rebind the Directory's files to the DataGrid after
      'deleting the file...

       Dim dirInfo As New DirectoryInfo(Server.MapPath("~\documents\"))
          articleList.DataSource = dirInfo.GetFiles("*.*")

     End Sub


<asp:Content ID='Content1' ContentPlaceHolderID='Main' Runat='Server'>

<br />
<h2>Upload Documents</h2>
	<p><a href="~\_documents.aspx" runat="server">Click here to Upload Documents</a>.</p>

<h2>View Delete Doucments</h2>

<p>Below is a list of files in the main directory.  If you choose to delete a file, this can not be undone.</p>

 <asp:label runat="server" id="lblMessage" Font-Italic="True" ForeColor="Red" />
  <asp:DataGrid runat="server" id="articleList" Font-Name="Verdana"
      AutoGenerateColumns="False" AlternatingItemStyle-BackColor="#eeeeee"
      HeaderStyle-BackColor="Navy" HeaderStyle-ForeColor="White"
      HeaderStyle-Font-Size="10.5pt" HeaderStyle-Font-Bold="True"
      <asp:ButtonColumn Text="Delete" ButtonType="PushButton" 
              CommandName="Delete" />
      <asp:HyperLinkColumn DataNavigateUrlField="Name" DataNavigateUrlFormatString="documents\{0}"
              DataTextField="Name" HeaderText="File Name" />
      <asp:BoundColumn DataField="LastWriteTime" 
              HeaderText="Last Write Time"
              DataFormatString="{0:d}" />
      <asp:BoundColumn DataField="Length" HeaderText="File Size"
	  	      DataFormatString="{0:#,### bytes}" />


'This is the file to upload documents to the documents folder.  The validation isn't correct, as it send validation to the client even when the file types are correct.

<%@ Page Language='VB' MasterPageFile='usphssite.master' Title='Content Page for documents.aspx' %>

<script runat='server'>

Protected Sub Button1_Click(ByVal sender As Object, _
   ByVal e As System.EventArgs)

        'Dim filepath As String = "C:\corpslinks\Veterinarian\documents"
        'Dim filepath As String = Server.MapPath("~\documents\")
        Dim filepath As String = Server.MapPath("~\documents")
   Dim uploadedFiles As HttpFileCollection = Request.Files
   Dim i As Integer = 0

   Do Until i = uploadedFiles.Count
     Dim userPostedFile As HttpPostedFile = uploadedFiles(i)

        If (userPostedFile.ContentLength > 0) Then
           Label1.Text += "<u>File #" & (i + 1) & "</u><br>"
           Label1.Text += "File Content Type: " & _
              userPostedFile.ContentType & "<br>"
           Label1.Text += "File Size: " & _
              userPostedFile.ContentLength & "kb<br>"
           Label1.Text += "File Name: " & _
              userPostedFile.FileName & "<br>"

           userPostedFile.SaveAs(filepath & "\" & _

           Label1.Text += "Location where saved: " & _
              filepath & "\" & _
              System.IO.Path.GetFileName(userPostedFile.FileName) & _
        End If
     Catch ex As Exception
        Label1.Text += "Error:<br>" & ex.Message
     End Try
     i += 1
End Sub


<asp:Content ID='Content1' ContentPlaceHolderID='Main' Runat='Server'>

<p>This page is used to upload documents to the documents folder.  These will be available to reference from your page once uploaded.</p>

	<p><a href="_documentlist.aspx" runat="server">Return to the document list</a>.</p>

<h2>Upload Doucments</h2>

<asp:FileUpload ID="FileUpload1" runat="server" /><br />
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="FileUpload1"
        Display="Dynamic" ErrorMessage="Please specify an image file." SetFocusOnError="True"
    <asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server" ControlToValidate="FileUpload1"
ErrorMessage="Upload .pdf, .doc, .ppt, and .xls files only." SetFocusOnError="True" 
        Display="Dynamic" ValidationGroup="Group1"></asp:RegularExpressionValidator><br />

<asp:FileUpload ID="FileUpload2" runat="server" /><br />

id="RegularExpressionValidator2" runat="server" 
ErrorMessage="Upload .pdf, .doc, .ppt, and .xls files only." 
Display="Dynamic" ValidationGroup="Group1">

<br />

<asp:FileUpload ID="FileUpload3" runat="server" /><br />

id="RegularExpressionValidator3" runat="server" 
ErrorMessage="Upload .pdf, .doc, .ppt, and .xls files only." 
Display="Dynamic" ValidationGroup="Group1">

<br />

<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" 
 Text="Upload File(s)" ValidationGroup="Group1"/>&nbsp;<br />
<br />
<asp:Label ID="Label1" runat="server"></asp:Label><br /><br />
<asp:Label ID="Label2" runat="server"></asp:Label><br /><br />
<asp:Label ID="Label3" runat="server"></asp:Label><br /><br />

<br />


Open in new window

atljarmanAuthor Commented:
I found the solution as C# on another site and converted it to VB.  This is functioning for my site.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.