Ich habe einen HttpHandler, der einige eingehende Anfragen überprüft und in bestimmten Fällen eine Funktion ausführt. Eine der Bedingungen, die überprüft werden müssen, ist, ob es sich bei der Anforderung um eine byte-range request handelt. Wie wird das gemacht?Erkennen von Bytebereich-Anfragen in .NET HttpHandler
Antwort
Sie benötigen für einen Range
-Header in der Request
Objekt zu suchen, die auf Ihre ProcessRequest
Methode übergeben Teil des HttpContext
ist. Es gibt keine Range
Eigenschaft in der HttpRequest
Klasse, so dass Sie in der Headers
suchen müssen. Wenn es eine Range
ist, wird es von der Form:
Range: bytes=<start>-<end>
Wo <start>
und <end>
ganze Zahlen sind.
Range: bytes=32768-98304
Sie werden den Text in Zahlen zu analysieren haben und behandeln entsprechend: Zum Beispiel, 64K aus der Mitte einer Datei wollte, wenn jemand.
Beachten Sie, dass die Range-Header-Syntax auch Dinge wie "0-500, 100-1500" (mehrere Bereiche) und "-500" (die letzten 500 Bytes) ermöglicht. Siehe RFC 2616 für die blutigen Details, die hier zu kurz sind.
Basierend auf dem Blog-Eintrag, der oben mit dem Kommentar von @ brent-keller verlinkt ist - der seinerseits auf CodePlex entry verweist - habe ich die untenstehenden Änderungen vorgenommen. Es wurde mit FDM (verfügbar here) getestet. MultiRange-Anfragen werden (noch) nicht unterstützt. No Web.config
Einträge sind erforderlich.
Die ursprüngliche Methode bei CodePlex enthält einen Fehler: Der Header Accept-Ranges
sollte einen Wert von bytes
haben, nicht den zurückzugebenden Bytebereich. Das gehört zum Content-Range
Header. Der Download funktioniert immer noch, aber Sie erhalten nicht byte serving, wenn Sie diesen Fehler machen.
Diese modifizierte Version wurde aus Gründen der Kürze und Lesbarkeit überarbeitet. Es hat auch den Vorteil, dass die zurückgegebene Datei nicht notwendigerweise an die tatsächliche URL gebunden ist - tatsächlich kann der Handler direkt vom Browser und gegebenenfalls mit Abfragezeichenfolgenargumenten aufgerufen werden. Dies ermöglicht die dynamische Datei-/Datenerstellung und -antwort.
Hoffentlich kann jemand etwas damit anfangen.
HTTP Handler
Public Class Upload
Implements IHttpHandler
Public Sub ProcessRequest(Context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim oFile As FileInfo
oFile = New FileInfo(Context.Server.MapPath("~/0HCJ0LE.zip"))
Me.UploadRange(Context, oFile)
End Sub
Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
Private Sub UploadRange(Context As HttpContext, File As FileInfo)
Dim oResponse As Response
Dim oRequest As Request
Dim _
nOffset,
nLength As Long
Using oReader As New StreamReader(File.FullName)
Context.Response.AddHeader("Accept-Ranges", "bytes")
oResponse = New Response(oReader)
oRequest = New Request(oResponse, Context)
If oRequest.HasRange Then
If oRequest.IsMultiRange Then
' At the moment we only support single ranges.'
' * Multiple range support requires some more work'
' * to comply with the specifications: http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2'
' *'
' * Multirange content must be sent with multipart/byteranges mediatype,'
' * (mediatype = mimetype)'
' * as well as a boundary header to indicate the various chunks of data.'
' '
' (?) Shoud this be issued here, or should the first'
' range be used? Or should the header be ignored and'
' we output the whole content?'
Me.ThrowBadRange(Context, oResponse)
Else
If oRequest.IsBadRange Then
Me.ThrowBadRange(Context, oResponse)
Else
Context.Response.StatusCode = 206
oResponse.Start = oRequest.Start
oResponse.End = oRequest.End
nOffset = oReader.BaseStream.Seek(oResponse.Start, SeekOrigin.Begin)
nLength = oResponse.End - oResponse.Start + 1
End If
End If
Else
nOffset = 0
nLength = oResponse.Size
End If
End Using
Context.Response.ContentType = MediaTypeNames.Application.Zip
Context.Response.AddHeader("Content-Disposition", $"attachment; filename={File.Name}")
Context.Response.AddHeader("Content-Length", nLength)
Context.Response.AddHeader(oResponse.HeaderName, oResponse.HeaderValue)
Context.Response.WriteFile(File.FullName, nOffset, nLength)
Context.Response.End()
End Sub
Private Sub ThrowBadRange(Context As HttpContext, Response As Response)
Context.Response.AddHeader(Response.HeaderName, Response.HeaderValue)
Throw New HttpException(416, "Requested range not satisfiable")
End Sub
End Class
Bereich anfordern
Friend NotInheritable Class Request
Public Sub New(Response As Response, Context As HttpContext)
Me.Response = Response
Me.Context = Context
End Sub
Public ReadOnly Property Start As Long
Get
If Me.Range(0) = String.Empty Then
Start = Me.Response.Size - Me.Range(1)
Else
Start = Me.Range(0)
End If
End Get
End Property
Public ReadOnly Property [End] As Long
Get
If Me.Range(0) = String.Empty Then
[End] = Me.Response.End
Else
If Long.TryParse(Me.Range(1), 0) Then
[End] = Me.Range(1)
Else
[End] = Me.Response.Size
End If
End If
[End] = Math.Min(Me.Response.End, [End])
End Get
End Property
Public ReadOnly Property HasRange As Boolean
Get
Return String.IsNullOrEmpty(Me.Context.Request.ServerVariables(HTTP_RANGE)) = False
End Get
End Property
Public ReadOnly Property IsMultiRange As Boolean
Get
Return Me.Context.Request.ServerVariables(HTTP_RANGE).Contains(",")
End Get
End Property
Public ReadOnly Property IsBadRange As Boolean
Get
Return Me.Start > Me.End OrElse Me.Start > Me.Response.Size - 1 OrElse Me.End >= Me.Response.Size
End Get
End Property
Private ReadOnly Property Range As List(Of String)
Get
Return Me.Context.Request.ServerVariables(HTTP_RANGE).Split("=")(1).Split("-").ToList
End Get
End Property
Private ReadOnly Response As Response
Private ReadOnly Context As HttpContext
Private Const HTTP_RANGE As String = "HTTP_RANGE"
End Class
Bereich Reaktions
Friend NotInheritable Class Response
Public Sub New(Reader As StreamReader)
_Size = Reader.BaseStream.Length
Me.End = Me.Size - 1
End Sub
Public Property Start As Long
Public Property [End] As Long
Public ReadOnly Property Size As Long
Public ReadOnly Property HeaderName As String
Get
Return "Content-Range"
End Get
End Property
Public ReadOnly Property HeaderValue() As String
Get
Return $"bytes {Me.Start}-{Me.End}/{Me.Size}"
End Get
End Property
End Class
- 1. Jede Möglichkeit, HttpHandler programmgesteuert in .NET hinzuzufügen?
- 2. Erkennen von Remote-DHCP-Servern in .NET
- 3. Erkennen von Abhängigkeiten zwischen Namespaces in .NET
- 4. Erkennen von https aus HttpContext in .net?
- 5. Httphandler ein Array zurückgeben
- 6. WiX erkennen. Net 4.0.3
- 7. Senden von Dateien in Chunks an HttpHandler
- 8. Erkennen von .NET Framework 4.5.1 mit WiX
- 9. Erkennen einer 3G-Internetverbindung in .NET
- 10. Kann ich in .NET Systemfokusereignisse (C#) erkennen?
- 11. Fingerabdrücke erkennen .Net Compact Framework
- 12. HttpHandler nicht umschreiben
- 13. So erkennen Sie Ton von Mikrofon in .net
- 14. .net Disconnect mit ReceiveAsync erkennen
- 15. HttpHandler mit Standard-Namespace
- 16. HttpHandler Path Problem ASP.NET
- 17. HttpHandler für WMV-Dateien
- 18. Erkennen von System Standby/Schlaf/Ruhezustand von .NET Windows Service?
- 19. ASP.NET HttpHandler Authentifizierungsproblem in Nicht-IE-Browser
- 20. HttpHandler Rückgabe Zero Länge Byte []
- 21. Wie erkennen Sie den .Net-Anwendungstyp?
- 22. Bild-Caching, Httphandler und FormsAuthentication
- 23. SharePoint 2007 und Erkennen. NET 3.5
- 24. Wie Verwenden von ASP.NET-Sitzungsstatus in einem HttpHandler?
- 25. Endlosschleife beim Aufruf eines HttpHandler
- 26. Httphandler nicht in IIS 7 arbeiten
- 27. Absturz in HttpHandler wegen Stream-Größe
- 28. AJAX HTTPHandler nicht aktualisieren Bild
- 29. Dotless HttpHandler mit VS2013 Vorschau
- 30. ASP.Net HttpHandler ProcessRequest() feuern zweimal
Gute Antwort. Im Interesse zukünftiger Generationen wäre ein kleiner Beispielcode wünschenswert. Sobald ich es umgesetzt habe, hoffe ich, dass es Ihnen nichts ausmacht, wenn ich es in Ihre Antwort injiziere. – Larsenal
@Larsenal: Ich habe keinen Beispielcode angegeben, weil ich keinen Code habe. Ich erinnere mich, dass ich vor einigen Jahren damit gearbeitet habe, aber der Code ist längst weg. Hoffentlich reicht meine kurze Beschreibung, um Sie zu beginnen. Es macht mir nichts aus, wenn du Code in meine Antwort eingibst. –
FWIW, dies führte zu mir, um den folgenden Beitrag mit Code zu finden, der zeigt, wie man mit dem Fernantrag umgehen kann: http://blogs.visigo.com/chriscoulson/easy-handling-of-http-range-requests-in-asp- Netz/ –