Я добавил в свое веб-приложение элемент управления загрузкой нескольких файлов AJAX. Когда я пытаюсь загрузить несколько файлов, загружается только 1-й файл, и в консоли Chrome dev отображается следующая ошибка:
Неперехваченная ошибка вызывает событие завершения загрузки и запускает новую загрузку
Мой контроль:
<cc1:AjaxFileUpload ID="multiUploader" ClientIDMode="Static" ClearFileListAfterUpload="false" OnClientUploadComplete="MultiUploadComplete" OnClientUploadCompleteAll="AllUploaded" OnUploadComplete="multiUploader_UploadComplete" MaximumNumberOfFiles="10" AllowedFileTypes="jpg,jpeg,png,gif" runat="server" />
JavaScript:
function MultiUploadComplete(sender, args) {
var filesize = args.get_fileSize();
var fileId = args.get_fileId();
var status = document.getElementById('multiUploader_FileItemStatus_' + fileId);
var container = document.getElementById('multiUploader_FileInfoContainer_' + fileId);
var fileName = $(container).find('span.filename').html();
if (filesize > 10240000) {
fileErrors += 1;
if (status.innerText) {
status.innerText = " (Error) " + $('#profilephotosize').attr('data-val').replace('{0}', fileName);
}
if (status.textContent) {
status.textContent = " (Error) " + $('#profilephotosize').attr('data-val').replace('{0}', fileName);
}
container.style.color = 'Red';
}
}
function AllUploaded() {
if (fileErrors > 0) {
alert($('#filesnotuploaded').attr('data-val').replace('{0}', fileErrors));
}
ShowData();
}
Backend code:
Private Function ResizeAndSaveImage(ByVal maxWidth As Integer, ByVal maxHeight As Integer, ByVal path As String, ByVal img As Image) As Boolean
'scale the image to maxWidth and maxHeight
'save image
Dim newWidth, newHeight As Integer
Dim scaleFactor As Double
Dim bResult As Boolean
newWidth = img.Width
newHeight = img.Height
If img.Width > maxWidth Or img.Height > maxHeight Then
If img.Width > maxWidth Then
scaleFactor = maxWidth / img.Width
newWidth = Math.Round(img.Width * scaleFactor, 0)
newHeight = Math.Round(img.Height * scaleFactor, 0)
End If
If newHeight > maxHeight Then
scaleFactor = maxHeight / newHeight
newWidth = Math.Round(newWidth * scaleFactor, 0)
newHeight = Math.Round(newHeight * scaleFactor, 0)
End If
End If
'code below copied from: http://www.webcosmoforums.com/asp/321-create-high-quality-thumbnail-resize-image-dynamically-asp-net-c-code.html
Try
Dim bmp As New Bitmap(newWidth, newHeight)
Dim gr As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(bmp)
gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality
gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality
gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High
Dim rectDestination As New System.Drawing.Rectangle(0, 0, newWidth, newHeight)
gr.DrawImage(img, rectDestination, 0, 0, img.Width, img.Height,
GraphicsUnit.Pixel)
bmp.Save(path)
System.IO.File.WriteAllBytes(ChangeExtension(path, "webp"), imageFunctions.EncodeImageToWebP(bmp))
bmp.Dispose()
bResult = True
Catch ex As Exception
End Try
Return bResult
End Function
Protected Sub afuPhoto_UploadedComplete(ByVal sender As Object, ByVal e As AjaxControlToolkit.AsyncFileUploadEventArgs)
Dim afuPhoto As AjaxControlToolkit.AsyncFileUpload = CType(sender, AjaxControlToolkit.AsyncFileUpload)
Dim pageId As Integer = 9
If ConfigurationManager.AppSettings("isDevelopment") = "false" Then
pageId = 1
End If
Dim allowedPhotos As Integer = ConfigurationManager.AppSettings("page_photos")
Dim TA As New mysiteTableAdapters.sitephotoalbumsTableAdapter
Dim totalPhotos As Integer = TA.CountPhotosForPageId(pageId)
Session("pageid") = pageId
'ReportError("afuPhoto_UploadedComplete.pageId", pageId.ToString)
If totalPhotos >= allowedPhotos Then
Exit Sub
End If
'code by mitsbits
If afuPhoto.HasFile AndAlso e.State = AjaxControlToolkit.AsyncFileUploadState.Success Then
'only if images are from same location, have same name and are uploaded at time calculated below a conflict could arise...chance minimal!
Dim d As String = (DateTime.Now.Millisecond + DateTime.Now.Second).ToString
If UploadFile(afuPhoto, pageId, d) = GlobalFunctions.ResultType.Success Then
'if file upload successfull update database with photo
TA.Insert(pageId, pageId.ToString + "_" + d + "_" + MakeValidImageName(afuPhoto.FileName), DateTime.Now)
End If
End If
End Sub
Protected Function UploadFile(ByVal FU As AjaxControlToolkit.AsyncFileUpload, ByVal locationId As Integer, ByVal curdate As String) As GlobalFunctions.ResultType
Dim filename As String = MakeValidImageName(FU.PostedFile.FileName)
Dim result As GlobalFunctions.ResultType
Dim thumbgalleryPath, galleryPath, largethumbgalleryPath As String
galleryPath = ConfigurationManager.AppSettings("page_photospath").ToString
thumbgalleryPath = ConfigurationManager.AppSettings("page_thumbsphotospath").ToString
largethumbgalleryPath = ConfigurationManager.AppSettings("page_largethumbsphotospath").ToString
If FU.PostedFile.FileName IsNot Nothing And FU.PostedFile.ContentLength > 0 Then
If FU.PostedFile.ContentLength <= 10240000 Then '10MB
If Not filename.ToLower.Contains(".jpg") And Not filename.ToLower.Contains(".png") And Not filename.ToLower.Contains(".gif") And Not filename.ToLower.Contains(".jpeg") Then
Return ResultType.notallowed
End If
Dim imgOriginal As Image = System.Drawing.Image.FromStream(FU.PostedFile.InputStream)
Dim imgOriginal1 As Image = imgOriginal 'this image is used as image is disposed
'save large image and save thumb image
If ResizeAndSaveImage(1200, 1200, Server.MapPath(galleryPath) + locationId.ToString + "_" + curdate + "_" + MakeValidImageName(filename), imgOriginal) And
ResizeAndSaveImage(450, 400, Server.MapPath(largethumbgalleryPath) + locationId.ToString + "_" + curdate + "_" + MakeValidImageName(filename), imgOriginal) And
ResizeAndSaveImage(75, 75, Server.MapPath(thumbgalleryPath) + locationId.ToString + "_" + curdate + "_" + MakeValidImageName(filename), imgOriginal) Then
result = ResultType.Success
End If
imgOriginal.Dispose()
End If
End If
If Not result = GlobalFunctions.ResultType.Success Then
'upload failed rollback
GlobalFunctions.DeleteFile(Server.MapPath(galleryPath) + locationId.ToString + "_" + filename)
GlobalFunctions.DeleteFile(Server.MapPath(largethumbgalleryPath) + locationId.ToString + "_" + filename)
GlobalFunctions.DeleteFile(Server.MapPath(thumbgalleryPath) + locationId.ToString + "_" + filename)
End If
Return result
End Function
Protected Sub multiUploader_UploadComplete(sender As Object, e As AjaxControlToolkit.AjaxFileUploadEventArgs) 'Handles multiUploader.UploadComplete
'check if the postback control was the linkbutton 'Opslaan', if it is, abort the upload function
'Dim ctrlname As String = Page.Request.Params.Get("__EVENTTARGET") 'PS. this code does NOT work when checking for postbacks with BUTTON controls
'If ctrlname.ToString <> "" AndAlso (ctrlname.Contains("btnSaveProfile") Or ctrlname.Contains("lbtnSetCoverPhoto")) Then 'save location button was clicked
' Exit Sub
'End If
'ReportError("multiUploader_UploadComplete")
Dim pageId = 1
Dim TAphotos As New mysiteTableAdapters.sitephotoalbumsTableAdapter
Dim DTphotos As mysite.sitephotoalbumsDataTable = TAphotos.GetPagePhotos(pageId)
Dim allowedPhotos As Integer = ConfigurationManager.AppSettings("page_photos")
Dim totalPhotos As Integer = DTphotos.Rows.Count
If totalPhotos >= allowedPhotos Then Exit Sub
'code by mitsbits
If e.State = AjaxControlToolkit.AjaxFileUploadState.Success Then 'multiUploader.afuPhoto.HasFile AndAlso
'only if images are from same location, have same name and are uploaded at time calculated below a conflict could arise...chance minimal!
'Dim d As String = (DateTime.Now.Millisecond + DateTime.Now.Second).ToString
Dim d As String = DateTime.Now.Second.ToString + "_" + DateTime.Now.Millisecond.ToString
Dim imageWidth, imageHeight As Integer
If e.FileSize > 10240000 Then
ScriptManager.RegisterClientScriptBlock(Me, Me.GetType(), "newfile",
"alert('file too large');", True)
Exit Sub
End If
'ReportError("e.filename", e.FileName.ToString)
Dim result As GlobalFunctions.ResultType = UploadMultiFile(System.Drawing.Image.FromStream(e.GetStreamContents), e.FileName, pageId, d, imageWidth, imageHeight)
If result = GlobalFunctions.ResultType.Success Then
'if file upload successfull update database with photo
Dim returnval As Integer
'Dim clientIPAddress As String = Request.ServerVariables("REMOTE_ADDR").ToString
returnval = TAphotos.Insert(pageId, pageId.ToString + "_" + d + "_" + MakeValidImageName(e.FileName), DateTime.Now)
ElseIf result = ResultType.invalidtype Then
' ' ScriptManager.RegisterClientScriptBlock(Me, Me.GetType(), "newfile",
' '"window.parent.$find('" + multiUploader.ClientID + "').newFileName='invalidfiletype';", True)
' Try
' ScriptManager.RegisterClientScriptBlock(Me, Me.GetType(), "newfile",
'"window.parent.$find('" + CType(dvSitePage.FindControl("multiUploader"), AjaxControlToolkit.AjaxFileUpload).ClientID + "').newFileName='invalidfiletype';", True)
' Catch ex As Exception
' End Try
End If
End If
End Sub
Protected Function UploadMultiFile(ByVal imgOriginal As Image, ByVal fileName As String, ByVal pageId As Integer, ByVal curdate As String, ByRef imageWidth As Integer, ByRef imageHeight As Integer) As GlobalFunctions.ResultType
fileName = MakeValidImageName(fileName)
Dim result As GlobalFunctions.ResultType
Dim thumbgalleryPath, origgalleryPath, photopathMedium As String
origgalleryPath = ConfigurationManager.AppSettings("page_photospath").ToString
photopathMedium = ConfigurationManager.AppSettings("page_largethumbsphotospath").ToString
thumbgalleryPath = ConfigurationManager.AppSettings("page_thumbsphotospath").ToString
Dim imgOriginal1 As Image = imgOriginal 'this image is used as image is disposed
'save large image and save thumb image
If ResizeAndSaveImage(1200, 1200, Server.MapPath(origgalleryPath) + pageId.ToString + "_" + curdate + "_" + fileName, imgOriginal) And', imageWidth, imageHeight
ResizeAndSaveImage(190, 190, Server.MapPath(photopathMedium) + pageId.ToString + "_" + curdate + "_" + fileName, imgOriginal) And
ResizeAndSaveImage(75, 75, Server.MapPath(thumbgalleryPath) + pageId.ToString + "_" + curdate + "_" + fileName, imgOriginal) Then
result = ResultType.Success
End If
imgOriginal.Dispose()
If Not result = GlobalFunctions.ResultType.Success Then
'upload failed rollback
GlobalFunctions.DeleteFile(Server.MapPath(origgalleryPath) + pageId.ToString + "_" + fileName)
GlobalFunctions.DeleteFile(Server.MapPath(thumbgalleryPath) + pageId.ToString + "_" + fileName)
GlobalFunctions.DeleteFile(Server.MapPath(photopathMedium) + pageId.ToString + "_" + fileName)
GlobalFunctions.DeleteFile(IO.Path.ChangeExtension(Server.MapPath(origgalleryPath) + pageId.ToString + "_" + fileName, "webp"))
GlobalFunctions.DeleteFile(IO.Path.ChangeExtension(Server.MapPath(thumbgalleryPath) + pageId.ToString + "_" + fileName, "webp"))
GlobalFunctions.DeleteFile(IO.Path.ChangeExtension(Server.MapPath(photopathMedium) + pageId.ToString + "_" + fileName, "webp"))
Else
'update successfull
End If
Return result
End Function
Я проанализировал вкладка Сеть:
А есть 3 запроса, последний как-то не работает:
Запрос 1 Имя: https://www.example.com/account/my-site?contextKey= {DA8BEDC8-B952-4d5d-8CC2-59FE922E2923} & controlID = multiUploader & start = 1 & queue = 2 & Статус: 200 Инициатор: https://www.example.com/ScriptResource.axd?d=-9YDjdHizPInlZIfdnhPn9wQrtV-icwCIGM6rMTgL1xcc9eo0V8JJ8oN6GiCmQReZbL-gv3nU-BhwRv3l8r5gubGD2yQ03ZVzdvO2Ko-nvG4Lmxrd4NQGjsi7m-ARIjq0&t=7d5986a
Запрос 2 Имя: https://www.example.com/AjaxFileUploadHandler.axd?contextKey= {DA8BEDC8-B952-4d5d-8CC2-59FE922E2923} & controlID = multiUploader & fileId = AF96CF7B-B0EF-A47F-36E6-4E75CABB28D8 & fileName = tt-ftp-settings.jpg * firstChunked = false Статус: 200 Инициатор: https://www.example.com/ScriptResource.axd?d=-9YDjdHizPInlZIfdnhPn9wQrtV-icwCIGM6rMTgL1xcc9eo0V8JJ8oN6GiCmQReZbL-gv3nU-BhwRv3l8r5gubGD2yQ03ZVzdvO2Ko-nvG4Lmxrd4NQGjsi7m-ARIjq0&t=7d5986a
Запрос 3 Имя: https://www.example.com/account/my-site?contextKey= {DA8BEDC8-B952-4d5d-8CC2-59FE922E2923} & controlID = multiUploader & done = 1 & guid = AF96CF7B-B0EF-A47F-36E6-4E75CABB28D8 & Статус: 500 Инициатор: https://www.example.com/ScriptResource.axd?d=-9YDjdHizPInlZIfdnhPn9wQrtV-icwCIGM6rMTgL1xcc9eo0V8JJ8oN6GiCmQReZbL-gv3nU-BhwRv3l8r5gubGD2yQ03ZVzdvO2Ko-nvG4Lmxrd4NQGjsi7m-ARIjq0&t=7d5986a
Здесь также проверено, но это также относится к AjaxFileUploadHandler.axd, а не к ScriptResource.axd. https://github.com/DevExpress/AjaxControlToolkit/issues/82
Я добавил ответ из sridharnethato для AjaxFileUploadHandler.axd в свой web.config: AjaxControlToolkit: ошибка, вызывающая событие завершения загрузки и начало новой загрузки Также пробовал другие ответы в этой теме.
Моя текущая проблема связана с ScriptResource.axd
, но я не знаю, почему запрос 1 успешен, а запрос 3 нет, хотя они выглядят практически одинаково.
Что я могу сделать, чтобы устранить вышеуказанную ошибку?
ОБНОВЛЕНИЕ 1
Начат тестовый ответ от @Greg, но я получаю сообщение об ошибке функции SaveImage
: {Message: "An error has occurred.", ExceptionMessage: "A generic error occurred in GDI+.",…}
ОБНОВЛЕНИЕ 2
Обнаружили проблему, очевидно, MapPath
вставляет маршрут в путь к файлу? Есть ли способ предотвратить это? Это мое определение:
<Route("api2/UploadFile/")>
Function UploadFile() As System.Web.Http.IHttpActionResult
Dim httpRequest = HttpContext.Current.Request
If ValidateImage(httpRequest.Files) Then
Dim file = httpRequest.Files(0)
Dim fileName = Path.GetFileName(file.FileName)
Dim galleryPath As String = ConfigurationManager.AppSettings("page_photospath").ToString
Dim filePath As String = HttpContext.Current.Server.MapPath(galleryPath) + fileName
===> HERE filePath IS: "C:\inetpub\example\api2\images\photos\Catan.jpg" where it should be: "C:\inetpub\example\images\photos\Catan.jpg"
Apparently `MapPath` is inserting the route into the path? Any way to prevent this?
SaveImage(file, filePath)
Return Ok()
Else
Return BadRequest()
End If
End Function