Simple generic handler serving image - asp.net

[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>

Related

Accessing SQL Server database from multiple webpages through asp.net

I am a new developer.
I have a problem of creating a website that needs to access one user account and retrieve all his information in that database through different webpages like one page for viewing his profile data; another page to view the exams that he already created ... etc.
What I did was for each single aspx page I had to create a new object and connect to the SQL Server database from that object which I feel there's something wrong with that.
The question is there any way that I can define the database object only once and make it accessible from different webpages in the same website and execute SQL queries from that object and retrieve data?
Thanks
We use this implementation using MVC...maybe you could adapt it to your needs:
clsConnectionManager
Imports System.Collections.Generic
Imports System.Linq
Imports System.Web
Imports System.Data.SqlClient
Imports System.Web.Configuration
Imports System.Data
Public Class clsConnectionManager
Implements IDisposable
<ThreadStatic> _
Private Shared pSqlConnection As SqlConnection
Private Shared pConnectionString As String
Public Shared ReadOnly Property Connection() As SqlConnection
Get
If pSqlConnection Is Nothing Then
pConnectionString = WebConfigurationManager.ConnectionStrings("DefaultConnection").ConnectionString
pSqlConnection = New SqlConnection(pConnectionString)
pSqlConnection.Open()
End If
If pSqlConnection.State = ConnectionState.Closed Then
pSqlConnection.Open()
End If
Return pSqlConnection
End Get
End Property
Public Sub Dispose() Implements System.IDisposable.Dispose
If pSqlConnection IsNot Nothing Then
pSqlConnection.Close()
End If
End Sub
End Class
Web.config
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=localhost;Initial Catalog=yourDBName;User ID=YourDBUserName;Password=YourUserPassword" providerName="System.Data.SqlClient" />
</connectionStrings>
Use
Inside your classes you could do something like this:
Public Sub dbGetAll()
Try
Using New clsConnectionManager()
Using lObjSQLCommand = New SqlClient.SqlCommand("StoredProcedureName", clsConnectionManager.Connection)
lObjSQLCommand.CommandType = CommandType.StoredProcedure
Using lObjSqlDataReader As SqlClient.SqlDataReader = lObjSQLCommand.ExecuteReader()
Do While lObjSqlDataReader.Read()
/*Read rows...*/
Loop
End Using
End Using
End Using
Catch ex As Exception
Throw ex
End Try
End Sub
You can define the connection settings in the web.config file and access the same in your.aspx page.
Refer http://www.connectionstrings.com/store-connection-string-in-webconfig/

Custom HTTPHandler is not getting called

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>

How to open a file formatted as a .NET config file to get a System.Configuration.Configuration object

I am in an ASP.NET app and I want to open a file, formatted similar to web.config or one of config files that you can link it to (appSettings, pages, etc.) and get the appSettings
Dim filePath As String = HostingEnvironment.MapPath("~/developer.config")
If (File.Exists(filePath)) Then
Dim map As New WebConfigurationFileMap()
map.MachineConfigFilename = filePath
Dim config As System.Configuration.Configuration = System.Web.Configuration.WebConfigurationManager.OpenMappedWebConfiguration(map, "/")
Dim developerAppSettings As AppSettingsSection = config.AppSettings
Return developerAppSettings
Else
Return Nothing
End If
I'd like developerAppSettings to be set to the appSettings section of my developer.config file, which looks like this:
<?xml version="1.0" encoding="utf-8"?>
<appSettings>
<add key="CustomerLogosFolder" value="C:\code\ExactBidTFS\RIMS\Development\CustomerLogos" />
</appSettings>
Apparently, I am not using OpenMappedWebConfiguration() correctly because it gives me an ArgumentOutOfRange exception (it appears to be the second, "/" parameter).
Is this even possible to do? I've tried OpenWebConfiguration() as well, but there seems to be some confusion as to what the file path parameter is used for in that situation. My experiments show that the file path is just a virtual directory that contains the web.config, not to specify my own developer.config file.
I saw this question while I was trying to look for a way to open my web app's config file from a console app. I also saw the post here that helped me.
I know it's an old question but I figured I might as well post my solution here.
I wrote the following snippet, which worked for me:
Dim map As New ExeConfigurationFileMap()
Dim filePath As String = "c:\temp\developer.config"
map.ExeConfigFilename = filePath
Dim configFile As Configuration = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None)
If configFile IsNot Nothing Then
Dim myAppSection As AppSettingsSection = TryCast(configFile.GetSection("appSettings"), AppSettingsSection)
Debug.Print(myAppSection.Settings("CustomerLogosFolder").Value)
End If
I also modified the xml a bit as below to make it similar to other config files:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="CustomerLogosFolder" value="C:\code\ExactBidTFS\RIMS\Development\CustomerLogos" />
</appSettings>
</configuration>
At the end of the execution I got "C:\code\ExactBidTFS\RIMS\Development\CustomerLogos" in my Immediate Window

How to make a fileupload interface in ASP.NET

I am trying to make a file upload interface in ASP.NET webforms and am looking for some advice on how to proceed.
The file upload interface is part of a website I am making on which users can post adverts. The interface is part of the "create a new advert" and will enable the user to upload up to 6 images. I am using only the asp.net FileUpload server control as I am trying to make a control which will work when users have javascript disabled. That's the background.
The upload for all 6 files occurs on button click. This stores the files in a temp folder (/UserUploads/temp) until the user submits the form in which case the files are moved to the /UserUploads folder and the references in the database or until the user hits the cancel button or navigates away in which case the files are deleted.
First question is: Is storing the files in a temp directory the right way to go about this? Or is there some better way of keeping the temp files on the server until the parent form is submitted? The only alternative I can think about is saving the files to the session, but that seems like a recipe for killing the server...
Second question: I am unclear what to do when the user just closes the browser window. I want to avoid ending up with a mess of orphaned files in the temp directory. Is there some way to make sure that all the files will get cleared out if the user doesn't go through with the form submission? Or do I just have to perform a cleanup of the temp directory every so often?
Third question: Am I doing this completely wrong and there is in fact a much better approach to uploading multiple files?
1) If you are using SQL Server, I personally prefer to store uploaded files in a varbinary(max) field and work with them by their unique ID. Then you don't have to worry about name collisions or de-sync of your DB to your filesystem. This also allows your upload process to be independent of the insertion of the parent form.
The examples below show how to grab the file stream (and metadata) from a FileUpload control in a FormView and supply it as a parameter to a SQL stored procedure. Then, a class implementing IHTTPHandler is used to retrieve files from the DB.
2) As far as clearing out temp files, I would associate each uploaded file with a temp master record so they are tied together. When the real master is confirmed, delete the temp master (and reference files from the real master). Then run a SQL Agent job on a regular interval to delete temp masters and associated files that are older than X amount of time.
Saving:
Protected Sub DetailsView1_ItemInserting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewInsertEventArgs) Handles DetailsView1.ItemInserting
Dim objUploader As FileUpload = DetailsView1.FindControl("fuFile")
If objUploader.HasFile Then
Dim strFileName As String = objUploader.PostedFile.FileName
strFileName = strFileName.Substring(strFileName.LastIndexOf("\") + 1)
Dim objFileStream As System.IO.Stream = objUploader.PostedFile.InputStream
Dim arrFileImageByteArray(objFileStream.Length) As Byte
objFileStream.Read(arrFileImageByteArray, 0, objFileStream.Length)
e.Values.Insert(0, "FileImage", arrFileImageByteArray)
e.Values.Insert(1, "FileName", strFileName)
e.Values.Insert(3, "PostingDate", Now)
e.Values.Insert(5, "Application", "CorpForms")
Else
e.Cancel = True
objMessages.Add(New StatusMessage(MessageType.Warning, "File Upload canceled. No file was selected."))
End If
End Sub
Retrieving:
Public Class FileServiceHandler : Implements IHttpHandler
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim idFileID As Guid
If context.Request.QueryString("FileID") IsNot Nothing Then
Dim strFileID As String = context.Request.QueryString("FileID")
Try
idFileID = Guid.Parse(strFileID)
Catch ex As Exception
Throw New Exception("Unable to parse File ID")
End Try
End If
Dim objConnection As New SqlConnection(ConfigurationManager.ConnectionStrings("PublicWebConnectionString").ConnectionString)
Dim objCommand As SqlCommand = objConnection.CreateCommand
Dim objReader As SqlDataReader
objCommand.CommandType = Data.CommandType.StoredProcedure
objCommand.CommandText = "spGetUploadedFile"
objCommand.Parameters.AddWithValue("FileID", idFileID.ToString)
Dim arrFileImage() As Byte = Nothing
Dim strFileName As String = String.Empty
Try
objConnection.Open()
objReader = objCommand.ExecuteReader
While objReader.Read
If Not IsDBNull(objReader("FileImage")) Then
arrFileImage = objReader("FileImage")
End If
If Not IsDBNull(objReader("FileName")) Then
strFileName = objReader("FileName")
End If
End While
Catch ex As Exception
Throw New Exception("There was a problem retreiving the file: " & ex.Message)
End Try
If objConnection.State <> Data.ConnectionState.Closed Then
objConnection.Close()
End If
If arrFileImage IsNot Nothing Then
context.Response.Clear()
context.Response.AddHeader("content-disposition", "attachment;filename=" & strFileName)
context.Response.BinaryWrite(arrFileImage)
context.Response.End()
Else
context.Response.ContentType = "text/plain"
context.Response.Write("Unable to retrieve file ID# " & idFileID.ToString)
End If
End Sub
Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return True
End Get
End Property
End Class
Web.Config in file retrieval path:
<configuration>
<system.web>
<httpHandlers>
<add verb="GET" path="*" type="MyNamespace.FileServiceHandler" />
</httpHandlers>
</system.web>
<system.webServer>
<handlers>
<add name="MyNamespace.FileServiceHandler" path="*" verb="*" type="MyNamespace.FileServiceHandler" resourceType="Unspecified" preCondition="integratedMode" />
</handlers>
</system.webServer>
</configuration>
File upload is always annoying. I recently found a great component that does what I belive all upload componentes should do.
See at:
http://aquantum-demo.appspot.com/file-upload
And a sample in C# at:
https://github.com/BoSchatzberg/jfu-CSharp-Example
And, you should store your files in a temporary folder before creating the database row. To avoid a mess of files left useless, you can use a windows temporary folder to delagate to the windows when delete or not those files.
System.IO.Path.GetTempPath()
I would recommend storing the files in the database, rather than a temporary folder.
Don't store them in Session Db - too much information, but include the SessionId in the Files Database record.
So you'd have a Files database with a table along the lines of
Id (int identity field)
Data (varbinary(max))
MimeType (varchar(50))
SessionId (varchar(50))
UserId ??
Then you'd simply need to write a scheduled SQL task to clear images where the session had expired.

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