Answered by:
Upload from ListView Insert

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