Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

IHttpModule and upload files

Status
Not open for further replies.

zerkat

Programmer
Jul 12, 2007
103
US
Hi. I have a requirement to upload large pdf files from a customer and after some thought decided to see if I can upload the file in chunks to hopefully lighten the load on the server a bit. I have the below code but it's not working properly. The resulting file is way too large and when I try to open it, it will not open. I receive an error that it is corrupted. I start with a file that is 20 MB and end up with a file that is closer to 1 GB. I wanted to look at what is coming in the request to see what all it's writing but have no idea how to or if I even can somehow display it.

I just read on another post that .NET is not capable of streaming files to the hard disk but that was from 2005. Is this still the case? This application is written in framework 2.0.

Code is below:

Imports System.Collections.Generic
Imports System.Text
Imports System.Web
Imports System.IO
Imports System.Web.UI
Imports System.Web.UI.WebControls

Namespace ChunkData
Public Class MyModule
Implements IHttpModule
Public Sub Init(app As HttpApplication) Implements IHttpModule.Init
AddHandler app.BeginRequest, New EventHandler(AddressOf app_BeginRequest)

End Sub
Private Sub app_BeginRequest(sender As Object, e As EventArgs)
Dim context As HttpContext = DirectCast(sender, HttpApplication).Context

If context.Request.ContentLength > 204800 Then

Dim provider As IServiceProvider = DirectCast(context, IServiceProvider)

Dim wr As HttpWorkerRequest = DirectCast(provider.GetService(GetType(HttpWorkerRequest)), HttpWorkerRequest)

Dim fs As FileStream = Nothing

' Check if body contains data

If wr.HasEntityBody() Then
' get the total body length
Dim requestLength As Integer = wr.GetTotalEntityBodyLength()

' Get the initial bytes loaded
Dim initialBytes As Integer = wr.GetPreloadedEntityBodyLength

If Not wr.IsEntireEntityBodyIsPreloaded() Then

Dim buffer As Byte() = New Byte(409600) {}

fs = New FileStream(context.Server.MapPath("~/Uploads/testdoc.pdf", FileMode.CreateNew)

' Set the received bytes to initial bytes before start reading
Dim receivedBytes As Integer = initialBytes
While requestLength - receivedBytes >= initialBytes
' Read another set of bytes
initialBytes = wr.ReadEntityBody(buffer, buffer.Length)
' Write the chunks to the physical file
fs.Write(buffer, 0, buffer.Length)
' Update the received bytes
receivedBytes += initialBytes
End While

initialBytes = wr.ReadEntityBody(buffer, requestLength - receivedBytes)
End If
End If
fs.Flush()
fs.Close()
End If

End Sub
Public Sub Dispose() Implements IHttpModule.Dispose
End Sub
End Class
End Namespace
 
I have a requirement to upload large pdf files from a customer and after some thought decided to see if I can upload the file in chunks to hopefully lighten the load on the server a bit
I'm not sure that by attempting to split the file up would actually reduce the load on the server as you still have to transfer x bytes to the server from the client.

I'd rethink the strategy and perhaps read up on some of the javascript asynchronous file upload options that have already been built.

I just read on another post that .NET is not capable of streaming files to the hard disk but that was from 2005.

You'll need to explain this comment this comment further.

Mark,

Darlington Web Design[tab]|[tab]Experts, Information, Ideas & Knowledge[tab]|[tab]ASP.NET Tips & Tricks
 
Hi Mark. Thanks for the advice. We suggested splitting the files to the client but they didn't like that option. I did see that there are some third party options out there - not sure if they will shell out the $ for them but will keep it in mind.

I read that no matter what .net will always load things into memory. There is no way around that. Like most things on the web, that's just the way it works.
 
You don't have to use a paid for service, there are many javascript and JQuery (for example) options that are free, have a read up and you should find them.

I'm still not sure what you mean by loading things into memory, can you give a clear and precise example of what the process would be and where you think .NET won't do what you want?

Mark,

Darlington Web Design[tab]|[tab]Experts, Information, Ideas & Knowledge[tab]|[tab]ASP.NET Tips & Tricks
 
ok - haven't seen many that were free but didn't do an extensive search either.

From what I have read, even if you use IHttpModule IIS still loads the request in memory before it hands it off to .net to do whatever. There is no direct way to have .NET just save the file to the hard disk unless you create your own hosting environment within .NET and bypass IIS altogether.
 
There is no direct way to have .NET just save the file to the hard disk unless you create your own hosting environment within .NET and bypass IIS altogether.
Unless it is an intranet environment then no, a client using a web browser on the internet will not have direct access to a file location on the web server. This exists no matter which server side programming language you use and with good reason too.

Mark,

Darlington Web Design[tab]|[tab]Experts, Information, Ideas & Knowledge[tab]|[tab]ASP.NET Tips & Tricks
 
oh duh - that does make sense.

i have not found any free controls that does what i need it to so really need to figure this one out. i think i am close with the code above but when the app gets to the ReadEntityBody the initialBytes variable looks too large in the beginning. Not sure how or why - if I knew how to view what was in the actual request that would be helpful.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top