0

I am trying to get the session value from a FileSystemHandler.ashx that I have in my project, but it's not returning anything.

'This is the relevant line of code
Dim str As String = DirectCast(_context.Request.QueryString("SessionID"),String)

Here is the method:

Public Sub ProcessRequest(ByVal context__1 As HttpContext) Implements IHttpHandler.ProcessRequest
        Context = context__1
        
        If Context.Request.QueryString("path") Is Nothing Then
            Exit Sub
        End If

        'Get the SessionState
        Dim str As String = DirectCast(_context.Request.QueryString("SessionID"),String)

        Initialize()
        
        Dim virtualPathToFile As String = Context.Server.HtmlDecode(Context.Request.QueryString("path"))
        Dim physicalPathToFile As String = ""

        For Each mappedPath As KeyValuePair(Of String, String) In mappedPathsInConfigFile
            If virtualPathToFile.ToLower().StartsWith(mappedPath.Key.ToLower()) Then
                ' Build the physical path to the file ;
                physicalPathToFile = virtualPathToFile.Replace(mappedPath.Key, mappedPath.Value).Replace("/", "\")
                
                ' Break the foreach loop
                Exit For
            End If
        Next
        
        'The docx files are downloaded
        If Path.GetExtension(physicalPathToFile).Equals(".docx", StringComparison.CurrentCultureIgnoreCase) Then
            ' Handle .docx files ;
            Me.WriteFile(physicalPathToFile, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", Context.Response)
        End If
        
        If Path.GetExtension(physicalPathToFile).Equals(".jpg", StringComparison.CurrentCultureIgnoreCase) Then
            ' Handle .jpg files ;
            WriteFile(physicalPathToFile, "image/jpeg", Context.Response)
        End If
        
        ' "txt/html" is the default value for the Response.ContentType property
        ' Do not download the file. Open in the window
        Context.Response.WriteFile(physicalPathToFile)
    End Sub

Imports System
Imports System.Data
Imports System.Configuration
Imports System.Web
Imports System.Web.SessionState
Imports System.Collections.Generic
Imports System.Xml
Imports DispatchSoftware
Imports System.IO

 Public Class FileSystemHandler
        Implements IHttpHandler
#Region "IHttpHandler Members"

    Private pathToConfigFile As String = "~/Incidents/MappingFile.mapping"
    **Private _context As HttpContext
    Private m_IncidentPath As String = Nothing
    Private m_SessionID As String
    Private Property Context() As HttpContext
        Get
            Return _context
        End Get
        Set(ByVal value As HttpContext)
            _context = value
        End Set
    End Property**
    
    Dim _itemHandlerPath As String
    Dim mappedPathsInConfigFile As Dictionary(Of String, String)

    Private Sub Initialize()

        If Not String.IsNullOrEmpty(Me.Context.Request.QueryString("SessionID")) Then
            m_SessionID = Me.Context.Request.QueryString("SessionID")
        End If


        If Not String.IsNullOrEmpty(Sessions.GetKeyValueSessionFile(m_SessionID, "IRPicturesPath")) Then
            m_IncidentPath = (Sessions.GetKeyValueSessionFile(m_SessionID, "IRPicturesPath"))
        End If

        Dim configFile As New XmlDocument()
        Dim physicalPathToConfigFile As String = Context.Server.MapPath(Me.pathToConfigFile)
        configFile.Load(physicalPathToConfigFile)
        ' Load the configuration file
        Dim rootElement As XmlElement = configFile.DocumentElement

        Dim handlerPathSection As XmlNode = rootElement.GetElementsByTagName("genericHandlerPath")(0)
        ' get all mappings ;
        Me._itemHandlerPath = handlerPathSection.InnerText

        Me.mappedPathsInConfigFile = New Dictionary(Of String, String)()
        Dim mappingsSection As XmlNode = rootElement.GetElementsByTagName("Mappings")(0)
        ' get all mappings ;
        For Each mapping As XmlNode In mappingsSection.ChildNodes
            Dim virtualPathAsNode As XmlNode = mapping.SelectSingleNode("child::VirtualPath")
            Dim physicalPathAsNode As XmlNode = mapping.SelectSingleNode("child::PhysicalPath")
            Me.mappedPathsInConfigFile.Add(PathHelper.RemoveEndingSlash(virtualPathAsNode.InnerText, "/"c), PathHelper.RemoveEndingSlash(physicalPathAsNode.InnerText, "\"c))
        Next
    End Sub
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Mark Zukerman
  • 85
  • 1
  • 3
  • 8

2 Answers2

2

You have to tell ASP.NET that the handler requires SessionState. Implement the IRequiresSessionState interface on your handler:

Public Class FileSystemHandler
    Implements IHttpHandler
    ' Note that IReadOnlySessionState will give you read access.
    '  This one seems to fit your current needs best, as you are not modifying SessionState.
    Implements IReadOnlySessionState 
    ' Note that IRequiresSessionState will give you read and SAFE write access
    'Implements IRequiresSessionState

  Private ReadOnly Property Session as HttpSessionState
    Get
       Return HttpContext.Current.Session
    End Get
  End Property

  '   ... and the rest of your code.

  ' sample method:
  Private Sub Test()
     Dim myValue As Object = Session("mykey")
  End Sub

End Class

http://msdn.microsoft.com/en-us/library/system.web.sessionstate.irequiressessionstate(v=vs.110).aspx

ps2goat
  • 8,067
  • 1
  • 35
  • 68
  • Can you please show me how to do it?? I created Interface IRequiresSessionState End Interface inside my class now what do I need to put there? – Mark Zukerman Sep 11 '14 at 17:38
  • 1
    Or probably `IReadOnlySessionState` as the OP does not appear to be writing to the session state: [IRequiresSessionState vs IReadOnlySessionState](http://stackoverflow.com/questions/8039014/irequiressessionstate-vs-ireadonlysessionstate). – Andrew Morton Sep 11 '14 at 17:39
  • I need help with creating this interface it's a little bit confusing Interface IRequiresSessionState Class Content : Implements IRequiresSessionState Dim requiresSession As Boolean = False 'If TypeOf (Context.Handler) Is IRequiresSessionState Then ' requiresSession = True 'End If End Class End Interface – Mark Zukerman Sep 11 '14 at 17:41
  • @MarkZukerman You don't need to do anything special: just use, e.g. `If context_1.Request.QueryString("path") Is Nothing Then` etc. – Andrew Morton Sep 11 '14 at 17:42
  • But I want to get the a value that I'm storing inside of the session file that's why I want to access it – Mark Zukerman Sep 11 '14 at 17:45
  • @MarkZukerman, you add that `Implements IRequiresSessionState` (if you need to read and write) or `Implements IReadOnlySessionState` (if you need to read only) after your class, as I've shown you in my code snippet. After that, you should be able to access the SessionState via `Dim mySession As HttpSessionState = HttpContext.Current.Session` – ps2goat Sep 11 '14 at 19:10
  • @AndrewMorton, updated, though I left in the other one in case others need a safe write to Session. – ps2goat Sep 11 '14 at 19:23
0

A complete example of a handler to send a file to the client for downloading could look like this:

Imports System.IO
Imports System.Web
Imports System.Web.Services

Public Class DownloadAnImage
    Implements System.Web.IHttpHandler, IReadOnlySessionState

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

        Dim accessLevel = CStr(context.Session("accessLevel"))
        Dim srcDir = "~/photos"

        If accessLevel = "full" Then
            ' adjust path to other images
        End If

        Dim fname = context.Request.QueryString("filename")
        Dim actualFile = Path.Combine(context.Server.MapPath(srcDir), fname) & ".jpg"

        If File.Exists(actualFile) Then
            context.Response.ContentType = "application/octet-stream"
            context.Response.AddHeader("content-disposition", "attachment; filename=""" & Path.GetFileName(actualFile) & """")
            context.Response.TransmitFile(actualFile)
        Else
            context.Response.Clear()
            context.Response.StatusCode = 404
            context.Response.Write("<html><head><title>File not found</title><style>body {font-family: Arial,sans-serif;}</style></head><body><h1>File not found</h1><p>Sorry, that file is not available for download.</p></body></html>")
            context.Response.End()

        End If

    End Sub

    ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
        Get
            Return False
        End Get
    End Property

End Class

(Abbreviated from actual working code.)

Notice that once you have declared Implements IReadOnlySessionState you have simple access to the session state.

Andrew Morton
  • 24,203
  • 9
  • 60
  • 84
  • Thank you for the respond but still the session value is returning nothing although I set on the top of the page Implements System.Web.IHttpHandler, IReadOnlySessionState and in the PorcessRequest function I added that code: Public Sub ProcessRequest(ByVal context__1 As HttpContext) Implements IHttpHandler.ProcessRequest Context = context__1 'Get the SessionState If Context.Request.QueryString("path") Is Nothing Then Dim str As String = DirectCast(Context.Request.QueryString("SessionID"),String) Exit Sub End If – Mark Zukerman Sep 11 '14 at 18:26
  • @MarkZukerman It would be easier to see the current state of your code if you would be so kind as to edit your original question - code doesn't show up very well in comments. – Andrew Morton Sep 11 '14 at 20:43