views:

41

answers:

2

I'm having issues with the way I've been reading my image datatype blobs from my SQL database (code below). This code works fine when I access this page directly. The PDF will open and works just fine. However, when I try to use this page to download a file and save it to the file-system programmatically, it fails (500 server error) and I've verified that it's the same URL either way.

So, my question is what is the best way to download a file from a database image datatype and save it to disk?

BondPDF.aspx

<%@ Page Language="VB" %>
<%@ Import Namespace="System.Collections.Generic" %> 

<script runat="server">
    Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs)
        Page.Theme = String.Empty ' disable theme
        If (Request.ServerVariables("HTTP_USER_AGENT").IndexOf("MSIE") > 0) Then
            Response.Cache.SetCacheability(HttpCacheability.Private)
        Else
            Response.Cache.SetCacheability(HttpCacheability.NoCache)
        End If
    End Sub

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim interns As IEnumerable(Of InternMag.Intern) = InternMag.Intern.GetInternForPhotoOrResume(New Guid(Request.QueryString("studentid")))
        For Each intern As InternMag.Intern In interns
            Response.ContentType = intern.ResumeFileType
            Response.AddHeader("Content-Disposition", "attachment; filename=""Resume" & intern.ResumeFileExtension & """")
            Response.BinaryWrite(CType(intern.ResumeFile.ToArray(), Byte()))
        Next
    End Sub
</script>
+2  A: 

The page works when you point a Browser to it, but it errors when you point your program to it. Perhaps your WebRequest is omitting the required studentid in the HTTP GET request. If you're getting an error 500, this error probably logs more details about why it failed on the server, and therefore the IIS/ASP error logs is the very first place to look.

As for the code you posted, reading an entire file in memory and then marshaling it into the Response is a horrible way to treat streams. It won't scale and will kill your server under load, due to the increased memory requirement per request. A sensible way would use CommandBehavior.SequentialAccess to obtain a SqlBytes.Stream and then write the content out chuk by chunk.

Remus Rusanu
Do you know where I can get an example of this implementation?
EdenMachine
A: 

Oh wow - this was WAY easier than I thought it was going to be...

System.IO.File.WriteAllBytes(CombinedDocumentPath, intern.ResumeFile.ToArray())
EdenMachine