locked
Upload from ListView Insert RRS feed

  • Question

  • User1510859543 posted

    I am trying to get my asp.net page to perform an insert and also to upload a file selected in a FileUpload control.  I am using an InsertItemTemplate in a ListView and then trying to upload the selected file using an ashx page.  The ashx page works fine as I am using it elsewhere.  I am getting the following error when trying to use a WebClient.  Below is the error.

    Message: Illegal characters in path.
    
     Stack Trace:
       at System.Security.Permissions.FileIOPermission.EmulateFileIOPermissionChecks(String fullPath)
       at System.Security.Permissions.FileIOPermission.QuickDemand(FileIOPermissionAccess access, String fullPath, Boolean checkForDuplicates, Boolean needFullPath)
       at System.Net.WebClient.GetUri(String path)
       at System.Net.WebClient.DownloadString(String address)
       at tables_PartInventory.SqlPartInventory_Inserted(Object sender, SqlDataSourceStatusEventArgs e) in C:\inetpub\wwwroot\BodyShop\tables\PartInventory.aspx.vb:line 97
       at System.Web.UI.WebControls.SqlDataSourceView.OnInserted(SqlDataSourceStatusEventArgs e)
       at System.Web.UI.WebControls.SqlDataSourceView.ExecuteDbCommand(DbCommand command, DataSourceOperation operation)
       at System.Web.UI.DataSourceView.Insert(IDictionary values, DataSourceViewOperationCallback callback)
       at System.Web.UI.WebControls.ListView.HandleInsert(ListViewItem item, Boolean causesValidation)
       at System.Web.UI.WebControls.ListView.HandleEvent(EventArgs e, Boolean causesValidation, String validationGroup)
       at System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args)
       at System.Web.UI.WebControls.ListViewItem.OnBubbleEvent(Object source, EventArgs e)
       at System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args)
       at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
    

    Below is the code in the DataSourceControl inserted event.

        Private Sub SqlPartInventory_Inserted(sender As Object, e As SqlDataSourceStatusEventArgs) Handles SqlPartInventory.Inserted
            Dim intNewVendorID As Int32 = Convert.ToInt32(e.Command.Parameters("@NewInventoryID").Value)
            txtInventoryIDNew.Text = intNewVendorID.ToString
    
            Dim client As WebClient = New WebClient()
            Dim strurl As String = "PartUpload.ashx?id=" & intNewVendorID.ToString
            Dim strReturn As String = client.DownloadString(strurl)
    
        End Sub

    Finally, the ashx page code.

    <%@ WebHandler Language="VB" Class="PartUpload" %>
    
    Imports System.Drawing
    Imports System.Drawing.Imaging
    
    Public Class PartUpload : Implements IHttpHandler
    
        Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
    
            If context.Request.Files.Count > 0 Then
                Dim file As HttpPostedFile = context.Request.Files(0)
                Dim directory As String = context.Server.MapPath("~/Photos/_Parts/")
    
                If System.IO.Directory.Exists(directory) = False Then
                    System.IO.Directory.CreateDirectory(directory)
                End If
    
                Dim img As String = String.Empty
                Dim bmpImg As Bitmap = Nothing
    
                Try
                    bmpImg = FilesClass.Resize_Image(file.InputStream, 2533, 1900)
                    'point to desired image location               
                    img = directory & context.Request.QueryString("id") & ".jpg"
                    bmpImg.Save(img, ImageFormat.Jpeg)
    
                Catch ex As Exception
                    context.Response.Write("Error occured: " & ex.Message.ToString())
    
                Finally
                    img = String.Empty
                    bmpImg.Dispose()
    
                End Try
    
            End If
    
        End Sub
    
        Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
            Get
                Return False
            End Get
        End Property
    
    End Class

    Tuesday, August 28, 2018 9:58 PM

Answers

  • User475983607 posted

    The WebClient code shown above does not pass files to the handler.  The handler code is specifically written to bypass the ID logic if no files exist in the context.   The current design simply will not work.  

    I recommend uploading the file(s), insert into the DB to get the ID, then name or rename the files, and save the files.   This should be done in one request not two.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, August 29, 2018 9:07 PM

All replies

  • User409696431 posted

    The error is "Illegal characters in path."   What is the full path name created by your code?

    Wednesday, August 29, 2018 1:09 AM
  • User-893317190 posted

    Hi dlchase,

    The parameter of the method DownloadString should be absolute path.Please change your relative path to absolute path and it should work.

    Below is my code.

    Page to call ashx.

     Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            Dim client As WebClient = New WebClient()
            Dim strurl As String = "http://localhost:55106/Handler1.ashx?id=1 ( ? "
            Dim strReturn As String = client.DownloadString(strurl)
            Response.Write(strReturn)
    
    
        End Sub

    The ashx.

     Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
    
            context.Response.ContentType = "text/plain"
    
            context.Response.Write(context.Request("id"))
    
        End Sub

    The result.

    Best regards,

    Ackerly Xu

    Wednesday, August 29, 2018 7:36 AM
  • User1510859543 posted

    I tries this but now I get the following error on the client.Downloadstring() method.

    Message: The remote server returned an error: (401) Unauthorized.
    
     Stack Trace:
       at System.Net.WebClient.DownloadDataInternal(Uri address, WebRequest& request)
       at System.Net.WebClient.DownloadString(Uri address)
       at tables_PartInventory.SqlPartInventory_Inserted(Object sender, SqlDataSourceStatusEventArgs e) in C:\inetpub\wwwroot\BodyShop\tables\PartInventory.aspx.vb:line 97
       at System.Web.UI.WebControls.SqlDataSourceView.OnInserted(SqlDataSourceStatusEventArgs e)
       at System.Web.UI.WebControls.SqlDataSourceView.ExecuteDbCommand(DbCommand command, DataSourceOperation operation)
       at System.Web.UI.DataSourceView.Insert(IDictionary values, DataSourceViewOperationCallback callback)
       at System.Web.UI.WebControls.ListView.HandleInsert(ListViewItem item, Boolean causesValidation)
       at System.Web.UI.WebControls.ListView.HandleEvent(EventArgs e, Boolean causesValidation, String validationGroup)
       at System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args)
       at System.Web.UI.WebControls.ListViewItem.OnBubbleEvent(Object source, EventArgs e)
       at System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args)
       at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
    
    

    Remember, I am processing an upload image fil;e in the ashx, if that makes a difference.

    Wednesday, August 29, 2018 5:51 PM
  • User475983607 posted

    The 401 indicates the request did not have proper rights to access a resource.  I guess the handler is in another site?  Is the other site secured in some way?

    On a side note, your original post mentions file upload but I don't see files being uploaded.

    Wednesday, August 29, 2018 6:17 PM
  • User1510859543 posted

    No the handler is in the same site.

    The file upload button is in the insert template of the ListView and the handler is being called from the inserted event of the sqldatasource control.

    Is the DownloadString the correct method to use?

    Wednesday, August 29, 2018 6:25 PM
  • User475983607 posted

    dlchase

    No the handler is in the same site.

    The file upload button is in the insert template of the ListView and the handler is being called from the inserted event of the sqldatasource control.

    Is the DownloadString the correct method to use?

    The posted code and your comments do not match.  The WebClient is calling the handler but there are no files passed just an querystring id=X.

    Dim strurl As String = "PartUpload.ashx?id=" & intNewVendorID.ToString
    Dim strReturn As String = client.DownloadString(strurl)
    

    Basically, there's not file passed by the WebClient.  If we assume the handler ran without the 401, then the handler would just return due to the IF below.

    If context.Request.Files.Count > 0 Then

    Can you explain the design?  It almost seems like you think two requests are combined somehow.

    Wednesday, August 29, 2018 6:41 PM
  • User1510859543 posted

    I am using the handler in the read-only template (item template) and calling it via ajax from jquery (see below).  That process works fine as I already have an ID on those rows.  I am trying to do the same in the insert template but I do not have an ID until the row is inserted, thus the call to the ashx page in the inserted event so I can pass the ID as the ID is used in the file name that is being uploaded from the FileUpload control on the page.

            /*
                The code below will immediately upload the selected file
                via the PartUpload.ashx page
            */
            $(function () {
                $('input[type="file"]').change(function (e) {
                    var formData = new FormData();
                    if (this.files.length > 0) {
                        var file = this.files[0];
                        formData.append("file", file);
                        formData.append("id", $(this).prop("id"));
    
                        if ($(this).prop("id") !== "fupPartPhoto") {
                            $.ajax({
                                type: 'post',
                                url: 'PartUpload.ashx?id=' + $(this).prop("id"),
                                contentType: false,
                                processData: false,
                                data: formData,
                                success: function (response) {
                                    window.location.reload();
                                }
                            });
                        }
                    }
                });
            });
    

    Wednesday, August 29, 2018 8:52 PM
  • User475983607 posted

    The WebClient code shown above does not pass files to the handler.  The handler code is specifically written to bypass the ID logic if no files exist in the context.   The current design simply will not work.  

    I recommend uploading the file(s), insert into the DB to get the ID, then name or rename the files, and save the files.   This should be done in one request not two.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, August 29, 2018 9:07 PM
  • User1510859543 posted

    OK, I think that will work.

    Wednesday, August 29, 2018 10:37 PM