Custom HTTPHandler is not getting called - asp.net

I'm trying to make a HTTPHandler that will authenticate certain static resources, PDF Files in this case.
I've added the following to my web.config:
<configuration>
<system.web>
<httpHandlers>
<clear />
<add path="*.pdf" verb="*" validate="true" type="AuthenticatedStaticResourceHandler" />
</httpHandlers>
</system.web>
</configuration>
Here's my HTTPHandler class:
Imports Microsoft.VisualBasic
Public Class AuthenticatedStaticResourceHandler
Implements IHttpHandler
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim resource As String = String.Empty
Select Case context.Request.HttpMethod
Case "GET"
resource = context.Server.MapPath(context.Request.FilePath)
If Helpers.User.CanAccessPath(context.Request.FilePath, context.User.Identity.Name) Then
SendContentTypeAndFile(context, resource)
Else
FormsAuthentication.RedirectToLoginPage()
End If
End Select
End Sub
Public ReadOnly Property IsReusable As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
Private Function SendContentTypeAndFile(ByVal context As HttpContext, ByVal file As String) As HttpContext
context.Response.ContentType = GetContentType(file)
context.Response.TransmitFile(file)
context.Response.End()
Return context
End Function
Private Function GetContentType(ByVal filename As String) As String
'Used to set the encoding for the reponse stream
Dim resource As String = String.Empty
Dim file As System.IO.FileInfo = New System.IO.FileInfo(filename)
If file.Exists Then
Select Case file.Extension.Remove(0, 1).ToLower()
Case "pdf"
resource = "application/pdf"
Case "jpg"
resource = "image/jpg"
Case "gif"
resource = "image/gif"
Case "png"
resource = "image/png"
Case "css"
resource = "text/css"
Case "js"
resource = "text/javascript"
Case Else
resource = String.Empty
End Select
End If
Return IIf(resource.Length > 0, resource, Nothing)
End Function
End Class
I've set a breakpoint on the Select Case context.Request.HttpMethod line in ProcessRequest, however when I try to access http://localhost/subfolder/subfolder/some.pdf the breakpoint is not triggered. Further, the example PDF I'm attempting to access is buried in a folder that I should not have access to, yet the PDF is served.
This leads me to believe that my HTTPHandler is not being called.
Am I missing something? What am I doing incorrectly?

Most likely, you have to add one extra part to your web.config to support all versions of IIS.
For IIS7 and higher, you need to register your handler in the system.webServer section:
<system.webServer>
<handlers>
<add ... />
</handlers>
</system.webServer>

Related

Not able to get connection string from Web.config file in asp.net 4.5

Currently I'm trying to connect SQL server DB from asp.net 4.5, keeping the connection string on Web.config file, using the following code to retrieve the connection string, but its retunr NULL value,
ConnectionStringSettings connString = ConfigurationManager.ConnectionStrings["ConString"];
SqlConnection Con = new SqlConnection(connString.ConnectionString);
the connection string in Web.Config is like
<connectionStrings>
<add name="ConString"
connectionString="Data Source=myservername;Initial Catalog=dbname;User ID=userid;Password=password;Integrated Security=True"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
I'm not understanding why it return null value, previously, in 3.5 I have used the following code to get the connection string,
Con = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConString"].ConnectionString);
it was working fine asp.net 3.5, but this also getting runtime error while using. Please let me know if I did any mistake.
Although, this is a mere suggestion/things to check, I am adding this as an answer
1) Can you please check if the web.config is at its right location?
2) Also, do you have any web.config (which overrides main web.config) in the same folder as that of your page?
Try below code:
string connectionstring = ConfigurationManager.ConnectionStrings["ConString"].ConnectionString.ToString();
I hope it will help you.. :)
I use this code. It works in our application.
If that doesn't work, you have some other problem.
Protected Shared strStaticConnectionString As String = Nothing
Public Shared Function GetConnectionString() As String
Return GetConnectionString(Nothing)
End Function
' Requires reference to System.Configuration
Public Shared Function GetConnectionString(ByVal strIntitialCatalog As String) As String
Dim strReturnValue As String = Nothing
If String.IsNullOrEmpty(strStaticConnectionString) Then
Dim strConnectionStringName As String = System.Environment.MachineName
If String.IsNullOrEmpty(strConnectionStringName) Then
strConnectionStringName = "LocalSqlServer"
End If
' Walk through the collection and return the first
' connection string matching the connectionString name.
Dim settings As System.Configuration.ConnectionStringSettingsCollection = System.Configuration.ConfigurationManager.ConnectionStrings
If (settings IsNot Nothing) Then
For Each cs As System.Configuration.ConnectionStringSettings In settings
If StringComparer.OrdinalIgnoreCase.Equals(cs.Name, strConnectionStringName) Then
strReturnValue = cs.ConnectionString
Exit For
End If
Next
End If
If String.IsNullOrEmpty(strReturnValue) Then
strConnectionStringName = "server"
Dim conString As System.Configuration.ConnectionStringSettings = System.Configuration.ConfigurationManager.ConnectionStrings(strConnectionStringName)
If conString IsNot Nothing Then
strReturnValue = conString.ConnectionString
End If
End If
settings = Nothing
strConnectionStringName = Nothing
Else
If String.IsNullOrEmpty(strIntitialCatalog) Then
Return strStaticConnectionString
End If
strReturnValue = strStaticConnectionString
End If
If String.IsNullOrEmpty(strReturnValue) Then
strReturnValue = GetConnectionString_Old()
If String.IsNullOrEmpty(strReturnValue) Then
Throw New ArgumentNullException("ConnectionString ""server"" in file web.config.")
End If
Else
Dim sb As New System.Data.SqlClient.SqlConnectionStringBuilder(strReturnValue)
If String.IsNullOrEmpty(strStaticConnectionString) Then
If Not sb.IntegratedSecurity Then
sb.Password = DeCrypt(sb.Password)
End If
strReturnValue = sb.ConnectionString
strStaticConnectionString = strReturnValue
End If
If Not String.IsNullOrEmpty(strIntitialCatalog) Then
sb.InitialCatalog = strIntitialCatalog
End If
strReturnValue = sb.ConnectionString
sb = Nothing
End If
Return strReturnValue
End Function ' GetConnectionString
Then this web.config file:
<?xml version="1.0"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<appSettings>
</appSettings>
<connectionStrings configSource="connections.config"/>
<system.web></system.web>
<system.webServer></system.webServer>
</configuration>
And this connection string file (connections.config)
<?xml version="1.0"?>
<connectionStrings>
<remove name="server"/>
<add name="server" connectionString="Data Source=localhost;
Initial Catalog=YOUR_DB;
Persist Security Info=False;
User Id=YOUR_USER;
Password=YOUR_PW;
MultipleActiveResultSets=False;
Packet Size=4096;
Application Name="YOUR_APPLICATION_NAME""
providerName="System.Data.SqlClient"/>
</connectionStrings>

How to retrieve custom settings from web.config

I have a web.config with some Custom Settings in it(not in appsettings) which look like this:
<ldapSettings>
<add key="server" value="xxxxxx"/>
<add key="portNumber" value="28400"/>
<add key="protocolVersion" value="3"/>
<add key="secure" value="true"/>
</ldapSettings>
How can I use the server address for my code?
I tried following
dim pfad As String
pfad = System.Configuration.ConfigurationManager.GetSection("ldapSettings")
Dim blas As String
blas =pfad["server"]
But it doesn't work. What am I missing?
You need to cast the return value of GetSection("ldapSettings") because it does not return string:
Dim ldap As ldapSettings = CType(ConfigurationManager.GetSection("ldapSettings"), ldapSettings)
Dim server As String = ldapSettings.server
First of all, you will need to define a class for your custom configuration section in order to tell ASP.NET what properties it has, like so:
Public Class ldapSettings
Inherits ConfigurationSection
Private Shared LSettings As ldapSettings = TryCast(ConfigurationManager.GetSection("ldapSettings"), ldapSettings)
Public Shared ReadOnly Property Settings() As ldapSettings
Get
Return LSettings
End Get
End Property
<ConfigurationProperty("server")>
Public Property Server() As String
Get
Return Me("server")
End Get
Set(value As String)
Me("server") = value
End Set
End Property
<ConfigurationProperty("portNumber")>
Public Property PortNumber() As String
Get
Return Me("portNumber")
End Get
Set(value As String)
Me("portNumber") = value
End Set
End Property
<ConfigurationProperty("protocolVersion")>
Public Property ProtocolVersion() As String
Get
Return Me("protocolVersion")
End Get
Set(value As String)
Me("protocolVersion") = value
End Set
End Property
<ConfigurationProperty("secure")>
Public Property Secure() As Boolean
Get
Return Me("secure")
End Get
Set(value As Boolean)
Me("secure") = value
End Set
End Property
End Class
Then, you will need to change your web.config file slightly. The XML layout of the custom section should look like this instead:
<configSections>
<section name="ldapSettings" type="Your_Assembly_Name.ldapSettings"/>
</configSections>
<ldapSettings
server="xxxxxx"
portNumber="28400"
protocolVersion="3"
secure="true"
/>
And then finally, you can get a setting using the following line:
Dim Secure As Boolean = ldapSettings.Settings.Secure
Sorry about the VB.NET, you can use this tool to convert if you need to: http://www.developerfusion.com/tools/convert/csharp-to-vb/
Info mainly sourced from here:
http://haacked.com/archive/2007/03/11/custom-configuration-sections-in-3-easy-steps.aspx
I found out a much simpler solution
here is what i did:
Private config As NameValueCollection
config = DirectCast(ConfigurationManager.GetSection("ldapSettings"), NameValueCollection)
Dim server As String
server = config.[Get]("server")
ConfigurationManager.AppSettings("keyname")
usually works for me
You can get help from following link
http://msdn.microsoft.com/en-us/library/610xe886%28v=vs.80%29.aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1

Simple generic handler serving image

[ASP.NET 4.0 Visual Studio 2010]
Hi I am new to ASP.NET and am just trying to:
Create a Generic Handler so my Server-Side image control can reference it like Image1.ImageUrl = "~/ImageHandle.ashx"
Pass the name of a file in my Dropbox account through the query, which is the image file's name (jpeg)
Rotate the image and serve it back to my calling code.
But I am really new and this is all I have, I don't know what i am doing wrong.
Public Class ImageHandle
Implements System.Web.IHttpHandler
Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim imgurl As String = "https://dl.dropbox.com/u/134313/Duel%20Portal%20Info/Images/" & context.Request("file").Replace("_", "%20") 'Number Changed for privacy reasons
context.Response.ContentType = "image/jpeg"
Dim img As System.Drawing.Image = Nothing
Dim webc As New Net.WebClient, theBytes() As Byte
Try
theBytes = webc.DownloadData(imgurl)
img = Byte2Image(theBytes)
img = Rotate90Degrees(img)
Catch ex As Exception
End Try
img.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg)
End Sub
End Class
The image just doesn't show up. ImageHandle hits no breakpoints at all.
Also I have no idea how to format web.config and include this. Help is much appreciated.
EDIT: This is my Web.Config so far. Still not working!! Please help!
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<handlers>
<add name="ImageHandle" path="~/ImageHandle.ashx" verb="*"/>
</handlers>
</system.webServer>

MembershipProvider and RequiresQuestionAndAnswer

We provide a website template for our customers to use as the basis of their websites. Our website has a custom membership provider.
We have had a problem raised by one customer. The customer sends out invitations to prospective members by email with a url to login the member. During registration they set their security question / answer.
However sometimes the prospective member loses the email (and therefore their password) but still tries to join the site.
The customer requested that the member be allowed to reset their password without the usual security question / answer when registration was not complete.
Unfortunately the MembershipProvider doesn't provide the username when requesting whether the question / answer are required. However it does call GetUser() just before.
To get this feature working I added a method (StartingPasswordRecovery) to my MembershipProvider to flag that password reset was active, calling it from the OnVerifyingUser event in the PasswordRecovery page.
While this code works I'm not convinced that it's very robust.
Can anyone point me towards a better solution.
Here's the relevant code I added to my membership provider.
Private _hasUserDefinedQuestionAndAnswer As Boolean
Private _isResettingPassword As Boolean
Public Overloads Overrides Function GetUser(ByVal username As String, ByVal userIsOnline As Boolean) As System.Web.Security.MembershipUser
...
_hasUserDefinedQuestionAndAnswer = ...
...
End Function
Public Overrides ReadOnly Property RequiresQuestionAndAnswer() As Boolean
Get
If Me._isResettingPassword Then
Me._isResettingPassword = False
Return Me.pRequiresQuestionAndAnswer And Me._hasUserDefinedQuestionAndAnswer
End If
Return Me.pRequiresQuestionAndAnswer
End Get
End Property
Public Sub StartingPasswordRecovery()
Me._isResettingPassword = True
End Sub
I'm not sure if i've understood you correctly, but couldn't you use the User-Profile to determine if a user requires question and answer or not?
web.config:
<profile defaultProvider="YourProfileProvider">
<providers>
<clear/>
<add name="YourProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ConnectionStringToDB" applicationName="/YourApp"></add>
</providers>
<properties>
<add name="RequiresQuestionAndAnswer" defaultValue="false" />
</properties>
</profile>
Custom membership-provider:
Public Overrides ReadOnly Property RequiresQuestionAndAnswer As Boolean
Get
If HttpContext.Current.User.Identity.IsAuthenticated Then
Dim userRequiresQuestionAndAnswer = _
CType(HttpContext.Current.Profile.GetPropertyValue("RequiresQuestionAndAnswer"), Boolean)
Return userRequiresQuestionAndAnswer
Else
Return MyBase.RequiresQuestionAndAnswer
End If
End Get
End Property
You could set it in your user-management page for every user individually:
HttpContext.Current.Profile.SetPropertyValue("RequiresQuestionAndAnswer", userRequiresQuestionAndAnswer)
HttpContext.Current.Profile.Save()
Edit:
according to your comment, i've modified the code a little bit. I hope that helps to get it working:
in custom membership-provider:
Public Overloads Overrides ReadOnly Property RequiresQuestionAndAnswer As Boolean
Get
If HttpContext.Current.User.Identity.IsAuthenticated Then
Return RequiresQuestionAndAnswer(Membership.GetUser.UserName)
Else
Return MyBase.RequiresQuestionAndAnswer
End If
End Get
End Property
Public Overloads ReadOnly Property RequiresQuestionAndAnswer(ByVal userName As String) As Boolean
Get
Dim profile As ProfileBase = ProfileBase.Create(userName)
If Not profile Is Nothing Then
Dim userRequiresQuestionAndAnswer = _
CType(profile.GetPropertyValue("RequiresQuestionAndAnswer"), Boolean)
Return userRequiresQuestionAndAnswer
Else
Return MyBase.RequiresQuestionAndAnswer
End If
End Get
End Property
where your PasswordRecovery-Control is:
Protected Sub VerifyingUser(ByVal sender As Object, ByVal e As LoginCancelEventArgs)
Dim login As WebControls.Login = DirectCast(Me.LoginView1.FindControl("Login1"), WebControls.Login)
Dim userName = DirectCast(login.FindControl("PwdRecovery"), PasswordRecovery).UserName
Dim RequiresQuestionAndAnswer = DirectCast(Membership.Provider, YourMembershipProvider).RequiresQuestionAndAnswer(userName)
'....'
End Sub

restrict access to doc files asp.net

i have a folder in my asp.net app conatining doc files that can be accessed only (dowwload) by a certain type of connected users(admin account or permitted other accounts)
how can i do that?
any ideas?
thanks in advance.
The App_Data folder in .NET is protected, and therefore ideal for this very purpose. I normally put sensitive files in here then have a page "ViewDoc.aspx" that performs the security checks and then sends the file to the user (using Response.Write).
Put sensitive files outside of web site root, so they can not be accessed by URL.
After that, use this HttpHandler (written in VB.NET) to serve files:
Public NotInheritable Class FileHandler
Implements IHttpHandler
Public ReadOnly Property IsReusable() As Boolean Implements System.Web.IHttpHandler.IsReusable
Get
Return False
End Get
End Property
Public Sub ProcessRequest(ByVal context As System.Web.HttpContext) Implements System.Web.IHttpHandler.ProcessRequest
If Not String.IsNullOrEmpty(context.Request.QueryString("FileName")) Then
Dim fileName As String = context.Request.QueryString("FileName")
Try
Dim filesPath As String = "D:\TheFiles\"
Dim fileInfo As New IO.FileInfo(filesPath & fileName)
If fileInfo.Exists Then
Dim fileExt As String = fileInfo.Extension.Remove(0, 1).ToUpperInvariant
If fileExt = "JPG" Then
context.Response.ContentType = "image/jpeg"
Else
context.Response.ContentType = "image/" & fileExt
End If
context.Response.TransmitFile(fileInfo.FullName)
End If
Catch ex As Exception
End Try
End If
End Sub
End Class
and register this handler in your web.config like this:
<httpHandlers>
<add verb="*" path="secfile.axd" type="MyApp.FileHandler, MyApp" validate="false"/>
</httpHandlers>
use like this:
<a href="secfile.axd?pic=sample.jpg" />
Remember adding your file types to handler and change response.contenttype by type of your file.
Using a handler is not the only way, you can use context.Response.TransmitFile(fileInfo.FullName) in your aspx file.
A simple way to do this is to NOT put these documents inside a folder of your ASP.NET app and instead, put it somewhere else in the file system that can't be accessed directly from the browser. Then programmatically, you can serve the file to the user if s/he's authorized to do so.

Resources