Search code examples
asp.nethttphandlerashxvirtual-directory

ASHX handler wont fire when path is entered


I have a file directory that can be access directly from the URL

e.g.

http://website.com/DirectoryName/folder/downloadpdf.pdf

I need to control whom can access the files so I have created a ASHX handler so I check permissions of the user.

however, when I access http://website.com/DirectoryName/ the handler doesnt get called.

I believe its something to do with my config, I have

  <location path="DirectoryName">
    <system.webServer>
      <handlers>
        <add name="PSHandler" path="DirectoryName/*" verb="*" type="ProjectName.PSHandler"/>
      </handlers>
    </system.webServer>
  </location>

Different way - IIS 6?

  <location path="DirectoryName">
    <system.web>
      <httpHandlers>
        <add path="DirectoryName/*" verb="*" type="ProjectName.PSHandler, PSHandler"/>
      </httpHandlers>
    </system.web>
  </location>

Is there something wrong with the above?

the ashx file

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

Imports System
Imports System.Web

Public Class PSHandler : Implements IHttpHandler

    Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
        context.Response.ContentType = "text/plain"
        context.Response.Write("Hello World")
    End Sub


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

End Class

FYI this is by running locally using IIS Express

Thanks


Solution

  • I think you are very close. One thing is you will need to write file to response.

    public class PSHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            string fileName = Path.GetFileName(context.Request.Path);
            string filePath = context.Server.MapPath("~/DirectoryName/" + fileName);
    
            // Check permission of user
    
            context.Response.ContentType = "application/pdf";
            context.Response.WriteFile(filePath);
        }
    
        public bool IsReusable
        {
            get { return false; }
        }
    }
    
    <system.webServer>
      <handlers>
        <add name="PS" path="DirectoryName/*" verb="*" 
           type="ProjectName.PSHandler, ProjectName" 
           preCondition="integratedMode"/>
      </handlers>
    </system.webServer>
    

    Update

    First of all, replace httpHandlers with authorization tag.

    <location path="DirectoryName">
       <system.web>
          <authorization>
             <deny users="*"/>
          </authorization>
       </system.web>
    </location>
    

    Then add handler inside application's web.config.

    <system.webServer>
       <handlers>
          <add name="PS" path="DirectoryName/*" verb="*" 
               type="ProjectName.PSHandler, ProjectName" 
               preCondition="integratedMode"/>
       </handlers>
    </system.webServer>
    

    Then copy and paste the following PSHandler code.

    Public Class PSHandler
        Implements IHttpHandler
        Public Sub ProcessRequest(context As HttpContext)
            Dim fileName As String = Path.GetFileName(context.Request.Path)
            Dim filePath As String = context.Server.MapPath(Convert.ToString("~/DirectoryName/") & fileName)
    
            ' Check permission of user. If permission denied, display 404 -
            ' context.Server.Transfer("~/404.aspx")
    
            context.Response.ContentType = "application/pdf"
            context.Response.WriteFile(filePath)
        End Sub
    
        Public ReadOnly Property IsReusable() As Boolean
            Get
                Return False
            End Get
        End Property
    End Class
    

    Reqeust URL should be like this -

    http://www.yourwebsite.com/DirectoryName/downloadpdf.pdf
    

    OR

    http://localhost:xxxx/DirectoryName/downloadpdf.pdf
    

    Please make sure downloadpdf.pdf file exists in DirectoryName folder.

    If it is still doesn't work, please create a new Web Application, and test the above code. I have tested and it works fine.