views:

97

answers:

2

My web app consists of images stored in the SQL Server db. And, i have a silverlight app on the client side. The web app would allow clients to download file from the server by triggering the download in the silverlight app. The Silverlight talks to the web service to download the file.

I am trying to understand the file download logic on the web service end. I could come up with following approaches:

1) Read the data from db to memory. Write memory data to a file on server. Return the server path to client. The client would invoke HtmlPage.Window.Navigate method with the url to prompt the user to download the file.

Disadvantage of the approach:
- Data from db needs to be written to file every time to download. Multiple simultaneous file download requests could clog the hard drive space on web server.

Is there any other approach to download the file? Does usage of FILESTREAM provide any better alternatives?

Appreciate your response!

+2  A: 

Since you've already got the DB with the images in the DB I'll gloss over the whole "should I store images in the DB question". I only mention it here because I'm sure that others will comment on it and dock me points for not mentioning that it's not the best idea. I'll just answer your question as best I can.

You can have a web service return an image directly. It's fairly straightforward...

Here's a code snippet from a web service I wrote just to see if you can do it. Hopefully, you can modify it for your needs.

<WebMethod()> _
    Public Function GetImage() As Byte()
        Try
            Dim outStream As New System.IO.MemoryStream
            Dim REturnValue As New System.Drawing.Bitmap(500, 500)
            Dim g As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(REturnValue)
            'g.RotateTransform(5)
            Dim f As New System.Drawing.Font(System.Drawing.FontFamily.GenericMonospace, 16, Drawing.FontStyle.Regular, Drawing.GraphicsUnit.Point)
            Dim b As System.Drawing.Brush = Drawing.Brushes.Lime

            g.DrawString("Hello", f, b, 0, 0)
            g.DrawString("Would you like to play a game? (Y/N)", f, b, 0, 40)
            g.DrawString("> Y", f, b, 0, 80)
            g.DrawString("Loading Global Thermonuclear War,", f, b, 0, 120)
            g.DrawString("please wait...", f, b, 0, 160)
            REturnValue.Save(outStream, System.Drawing.Imaging.ImageFormat.Jpeg)

            Return outStream.ToArray()
        Catch ex As Exception
            Throw New Exception(ex.ToString())
        End Try

    End Function

and then the Asp.Net page that displays the image..

 Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim ts As New TestServices
        Dim b As System.Drawing.Bitmap
        Dim bytes As Byte()
        Dim inStream As System.IO.MemoryStream

        bytes = ts.GetImage()
        inStream = New System.IO.MemoryStream(bytes)
        b = New System.Drawing.Bitmap(inStream)
        Response.ContentType = "image/jpeg"
        b.Save(Response.OutputStream, b.RawFormat)
        b.Dispose()
    End Sub
David Stratton
Yuck! No Using/End Using. -1 for that.
John Saunders
+2  A: 

This is David Stratton's answer, just cleaned up:

<WebMethod()> _
Public Function GetImage() As Byte()
    Using outStream As New System.IO.MemoryStream
        Using ReturnValue As New System.Drawing.Bitmap(500, 500)
            Using g As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(ReturnValue)
                'g.RotateTransform(5)
                Using f As New System.Drawing.Font(System.Drawing.FontFamily.GenericMonospace, 16, Drawing.FontStyle.Regular, Drawing.GraphicsUnit.Point)
                    Dim b As System.Drawing.Brush = Drawing.Brushes.Lime

                    g.DrawString("Hello", f, b, 0, 0)
                    g.DrawString("Would you like to play a game? (Y/N)", f, b, 0, 40)
                    g.DrawString("> Y", f, b, 0, 80)
                    g.DrawString("Loading Global Thermonuclear War,", f, b, 0, 120)
                    g.DrawString("please wait...", f, b, 0, 160)
                    ReturnValue.Save(outStream, System.Drawing.Imaging.ImageFormat.Jpeg)

                    Return outStream.ToArray()
                End Using
            End Using
        End Using
    End Using
End Function


Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Using ts As New TestServices
        Dim bytes As Byte() = ts.GetImage()
        Using inStream As System.IO.MemoryStream = New System.IO.MemoryStream(bytes)
            Using b As System.Drawing.Bitmap = New System.Drawing.Bitmap(inStream)
                Response.ContentType = "image/jpeg"
                b.Save(Response.OutputStream, b.RawFormat)
            End Using
        End Using
    End Using
End Sub
John Saunders
That looks much better.
David Stratton