Using: C#, .NET 3.5 web forms application, fluent nhibernate 1.1.0.685, SQL Server 2008R2
I have a web app that allows users to upload files and attach them to "cases" they are working. The files are stored in the database as varbinary(MAX).
Here is the code I'm currently using to download the files:
...
if (!SiteUserService.HasPermission(Domain.SiteUserService.SitePermissions.ModifyCase, CurrentUser))
this.AccessDenied();
string attachmentId = Request.QueryString["f"].ToString();
DownloadFileResponse response = CaseService.RetrieveAttachment(attachmentId, CurrentUser.Id);
DownloadAttachment(response.Attachment.ContentType, response.Attachment.FileName, response.FileBytes);
...
protected void DownloadAttachment(string mimeType, string fileName, byte[] file)
{
Response.Clear();
Response.ContentType = mimeType;
Response.AddHeader("content-disposition", string.Format("attachment;filename=\"{0}\"", fileName));
Response.BinaryWrite(file);
Response.Flush();
Response.End();
}
This works just fine for smaller files. A couple files were uploaded yesterday, sizes (in bytes): 2230165, 2104051, 1024274, and 2202318. When the users try to download these files they receive a "Request Timed Out" error. The majority of the files are around 45572 bytes.
The application in question resides in the DMZ, so we are using WCF services for data access, no direct SQL calls, so a solution like this won't work.
I don't have a physical file in the file system, so I don't think this code (below) will work:
System.IO.Stream stream = null;
byte[] buffer = new Byte[10000];
int length;
long dataToRead;
string filePath = context.Request.PhysicalPath;
string fileName = System.IO.Path.GetFileName(filePath);
try
{
stream = new System.IO.FileStream(filePath, System.IO.FileMode.Open,
System.IO.FileAccess.Read,System.IO.FileShare.Read);
dataToRead = stream
context.Response.ContentType = "application/octet-stream";
context.Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
while(dataToRead > 0)
{
if(context.Response.IsClientConnected)
{
length = stream (buffer, 0, 10000);
context.Response.OutputStream.Write(buffer, 0, length);
context.Response.Flush();
buffer= new Byte[10000];
dataToRead = dataToRead - length;
}
else
{
dataToRead = -1;
}
}
}
catch(Exception ex)
{
throw(ex);
}
finally
{
if(stream != null)
{
stream ();
}
}
Any suggestions for how I can allow files to be downloaded in "chunks"?
Edit: I also looked at this solution, but don't know how I would implement it with just a byte[] from the DB.