3

我正在尝试使用通用处理程序上传图像,如下所示,我有一个普通的 aspx 页面,上传后显示所有上传的图像。一切正常。

<%@ WebHandler Language="VB" Class="Upload"%>

Imports System
Imports System.Web
Imports System.Threading 
Imports System.Web.Script.Serialization
Imports System.IO

Public Class Upload : Implements IHttpHandler, System.Web.SessionState.IRequiresSessionState 
    Public Class FilesStatus
        Public Property thumbnail_url() As String
        Public Property name() As String
        Public Property url() As String
        Public Property size() As Integer
        Public Property type() As String
        Public Property delete_url() As String
        Public Property delete_type() As String
        Public Property [error]() As String
        Public Property progress() As String
    End Class
    Private ReadOnly js As New JavaScriptSerializer()
    Private ingestPath As String

    Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest


            Dim r = context.Response
            ingestPath = context.Server.MapPath("~/UploadedImages/")

            r.AddHeader("Pragma", "no-cache")
            r.AddHeader("Cache-Control", "private, no-cache")

            HandleMethod(context)
    End Sub
    Private Sub HandleMethod(ByVal context As HttpContext)
        Select Case context.Request.HttpMethod
            Case "HEAD", "GET"
                ServeFile(context)

            Case "POST"
                UploadFile(context)

            Case "DELETE"
                DeleteFile(context)

            Case Else
                context.Response.ClearHeaders()
                context.Response.StatusCode = 405
        End Select
    End Sub
    Private Sub DeleteFile(ByVal context As HttpContext)
        Dim filePath = ingestPath & context.Request("f")
        If File.Exists(filePath) Then
            File.Delete(filePath)
        End If
    End Sub
    Private Sub ServeFile(ByVal context As HttpContext)
        If String.IsNullOrEmpty(context.Request("f")) Then
            ListCurrentFiles(context)
        Else
            DeliverFile(context)
        End If
    End Sub

    Private Sub UploadFile(ByVal context As HttpContext)
        Dim statuses = New List(Of FilesStatus)()
        Dim headers = context.Request.Headers

        If String.IsNullOrEmpty(headers("X-File-Name")) Then
            UploadWholeFile(context, statuses)
        Else
            UploadPartialFile(headers("X-File-Name"), context, statuses)
        End If


        WriteJsonIframeSafe(context, statuses)
    End Sub

    Private Sub UploadPartialFile(ByVal fileName As String, ByVal context As HttpContext, ByVal statuses As List(Of FilesStatus))
        If context.Request.Files.Count <> 1 Then
            Throw New HttpRequestValidationException("Attempt to upload chunked file containing more than one fragment per request")
        End If
        Dim inputStream = context.Request.Files(0).InputStream
        Dim fullName = ingestPath & Path.GetFileName(fileName)

        Using fs = New FileStream(fullName, FileMode.Append, FileAccess.Write)
            Dim buffer = New Byte(1023) {}

            Dim l = inputStream.Read(buffer, 0, 1024)
            Do While l > 0
                fs.Write(buffer, 0, l)
                l = inputStream.Read(buffer, 0, 1024)
            Loop
            fs.Flush()
            fs.Close()
        End Using

        statuses.Add(New FilesStatus With {.thumbnail_url = "Thumbnail.ashx?f=" & fileName, .url = "Upload.ashx?f=" & fileName, .name = fileName, .size = CInt((New FileInfo(fullName)).Length), .type = "image/png", .delete_url = "Upload.ashx?f=" & fileName, .delete_type = "DELETE", .progress = "1.0"})

    End Sub

    Private Sub UploadWholeFile(ByVal context As HttpContext, ByVal statuses As List(Of FilesStatus))
        For i As Integer = 0 To context.Request.Files.Count - 1
            Dim file = context.Request.Files(i)
            file.SaveAs(ingestPath & Path.GetFileName(file.FileName))
            Thread.Sleep(1000)
            Dim fname = Path.GetFileName(file.FileName)
            statuses.Add(New FilesStatus With {.thumbnail_url = "Thumbnail.ashx?f=" & fname, .url = "Upload.ashx?f=" & fname, .name = fname, .size = file.ContentLength, .type = "image/png", .delete_url = "Upload.ashx?f=" & fname, .delete_type = "DELETE", .progress = "1.0"})
        Next i
    End Sub

    Private Sub WriteJsonIframeSafe(ByVal context As HttpContext, ByVal statuses As List(Of FilesStatus))
        context.Response.AddHeader("Vary", "Accept")
        Try
            If context.Request("HTTP_ACCEPT").Contains("application/json") Then
                context.Response.ContentType = "application/json"
            Else
                context.Response.ContentType = "text/plain"
            End If
        Catch
            context.Response.ContentType = "text/plain"
        End Try

        Dim jsonObj = js.Serialize(statuses.ToArray())
        context.Response.Write(jsonObj)
    End Sub
    Private Sub DeliverFile(ByVal context As HttpContext)
        Dim filePath = ingestPath & context.Request("f")
        If File.Exists(filePath) Then
            context.Response.ContentType = "application/octet-stream"
            context.Response.WriteFile(filePath)
            context.Response.AddHeader("Content-Disposition", "attachment, filename=""" & context.Request("f") & """")
        Else
            context.Response.StatusCode = 404
        End If
    End Sub
    Private Sub ListCurrentFiles(ByVal context As HttpContext)
        Dim files = New List(Of FilesStatus)()

        Dim names = Directory.GetFiles(context.Server.MapPath("~/UploadedImages/"), "*", SearchOption.TopDirectoryOnly)

        For Each name In names
            Dim f = New FileInfo(name)
            files.Add(New FilesStatus With {.thumbnail_url = "Thumbnail.ashx?f=" & f.Name, .url = "Upload.ashx?f=" & f.Name, .name = f.Name, .size = CInt(f.Length), .type = "image/png", .delete_url = "Upload.ashx?f=" & f.Name, .delete_type = "DELETE"})
        Next name

        context.Response.AddHeader("Content-Disposition", "inline, filename=""files.json""")
        Dim jsonObj = js.Serialize(files.ToArray())
        context.Response.Write(jsonObj)
        context.Response.ContentType = "application/json"
    End Sub
    Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
        Get
            Return False
        End Get
    End Property

End Class

现在我想通过生成一个随机字符串来添加一个会话变量,并将上传的图像添加到新创建的随机字符串中。

1.我已经在 SO 上看到了这个用于会话的问题System.Web.SessionState.IRequiresSessionState ,以及我如何使用它并将我的图像添加到该文件夹​​中,然后我如何create在我的页面中使用这个会话变量。folderaccessnormal aspx

2.(或)更好的方法是在 aspx 页面中创建会话变量并将其传递给处理程序?如果是这样我该怎么做?

3 .我试图从我的处理程序中找到控件。这可能吗?如果有人知道如何得到这个,那么我的问题也将得到解决,因此我试图从 m aspx 页面创建一个会话。

谁能解释处理这种情况的更好方法。

4

2 回答 2

3

我完全同意jbl的评论。

  1. 您可以使用项目中的任何位置获取和设置会话HttpContext.Current.Session
  2. 无论您在哪里创建会话。只需在访问之前确保会话存在即可。
  3. 不知道你到底在问什么(需要更多解释)。

这是一个示例,我在 HttpHandler 上使用了会话。但是,它是在 c# 上的(希望你能理解)。

于 2012-04-13T16:58:11.310 回答
0

这不是一个真正的答案,但@Knvn 写了一个我无法理解的 C# 示例,因此我使用转换器将其转换为 VB。把它贴在这里以防将来对某人有帮助。

Public Class HttpHandler
    Implements IHttpHandler
    Implements IRequiresSessionState
    Public Sub New()
    End Sub

    Public Sub ProcessRequest(context As HttpContext)
        Dim Request As HttpRequest = context.Request
        Dim Response As HttpResponse = context.Response

        If SessionHandler.Current.UserID = 0 Then
            Response.Redirect("~/Default.aspx")
        Else
            Try
                If Request.Path.EndsWith(".pdf") Then
                    Dim client As New WebClient()
                    Dim buffer As [Byte]() = client.DownloadData(HttpContext.Current.Server.MapPath(Request.Path))
                    Response.ContentType = "application/pdf"
                    Response.AddHeader("content-length", buffer.Length.ToString())
                    Response.BinaryWrite(buffer)
                Else
                    Using reader As New StreamReader(HttpContext.Current.Server.MapPath(Request.Path))
                        Response.Write(reader.ReadToEnd())
                    End Using
                End If
            Catch
                Response.Redirect("~/Default.aspx")
            End Try
        End If
    End Sub

    Public ReadOnly Property IsReusable() As Boolean
        ' To enable pooling, return true here.
        ' This keeps the handler in memory.
        Get
            Return False
        End Get
    End Property
End Class
于 2012-08-27T06:45:10.087 回答