在asp.net处理程序中访问会话

时间:2012-04-13 15:25:45

标签: asp.net vb.net session handler

我正在尝试使用通用处理程序上传图像,如下所示,我有一个普通的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上看到这个Question使用System.Web.SessionState.IRequiresSessionState进行会话,我如何create folder使用access并将我的图片添加到该文件夹​​中这样做我如何在normal aspx页面中{{1}}此会话变量。

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

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

任何人都可以解释处理这种情况的更好方法。

2 个答案:

答案 0 :(得分:3)

我完全同意jbl的评论。

  1. 您可以在项目的任何位置使用HttpContext.Current.Session获取和设置会话。
  2. 无论您在何处创建会话。在访问会话之前,请确保会话存在。
  3. 不确定你在这里问的是什么(需要更多解释)。
  4. Here is an example,我在HttpHandler上使用了session。但是,它是在c#上(希望你能理解)。

答案 1 :(得分: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