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.IRequiresSessionStatecreatefolderaccessnormal aspx

2.(または)aspxページでセッション変数を作成し、それをハンドラーに渡すのがより良い方法ですか?もしそうなら、どうすればそれを行うことができますか?

3.ハンドラーからコントロールを見つけようとしています。それは可能ですか?誰かがこれを取得する方法を知っている場合は、問題も解決されるので、maspxページからセッションを作成しようとしています。

誰かがこの状況を処理するためのより良い方法を説明できますか?

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 に答える