Link to home
Start Free TrialLog in
Avatar of bigd2001grad
bigd2001gradFlag for United States of America

asked on

Add a linkbutton to download a file located on the server

I'm developing a web application written in C# and using .NET 1.1.

I want each user to download an excel file via a link button - such that when they click the linkbutton, a "save as" dialog appears so the user can save the file to his/her client machine.

I don't need anything fancy - the only other way I know to do this is very complicated (adding the file as a resource and extracting it before download).

Thank you in advance.
ASKER CERTIFIED SOLUTION
Avatar of nauman_ahmed
nauman_ahmed
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
bigd2001grad,

Potentially an even easier way might be to use the Response.WriteFile() method.  See this link:
http://aspalliance.com/articleViewer.aspx?aId=259&pId=-1

Good luck.
-- Jason
This should do it

HttpContext.Current.Response.Clear();
HttpContext.Current.Response.Charset ="";
HttpContext.Current.Response.ContentType ="application/msword";
string strFileName = "myfile.xls";
HttpContext.Current.Response.AddHeader("Content-Disposition",
  "inline;filename=" + strFileName);
 
HTH
Avatar of bigd2001grad

ASKER

if the file is an excel file, would the content type be "application/msexcel"?
I can get the "save as" dialog to appear and can save the file, but everytime I open the file - it simply contains data from my web page.

Does this mean the response can't find my file or am I missing something?
For EXCEL you have to use application/vnd.ms-excel content type

Are you sure you are using Response.Clear(); before rendering the content?

--Nauman.
Yeah, Response.Clear is there.

Could it be caused by a postback or some other event that populates the response object?
What type of HTML output you have in the generateed XML file?

--Nauman.
the excel file contains a bunch of information generated by my javascript menu and a few of the web controls form the home page.
Avatar of Ashutosh Vyas
User Response.End at the end to avoid that
bigd2001grad,

This excel file is generated on runtime?

--Nauman.
Nauman,

The file is not generated at runtime - it already exists in my solution
did Response.End not help?
no, Response.End didn't seem to do anything...
Does this make sense to anyone?  Maybe I should try embedding my Excel file as a resource (making it a bit easier to deploy to different environments)...

string myDirectory = EnvironmentHandler.Instance.ActiveEnvironment.EnvironmentSettings.GetSettingValue("FileDirectory");
                  FileUtil.EnsureDirectoryExists(myDirectory);

                  // Get embedded resource stream.
                  Assembly assembly = Assembly.GetExecutingAssembly();
                  string[] assemblyNameParts = assembly.FullName.Split(',');
                  Stream resourceStream = assembly.GetManifestResourceStream("File.xls");

                  string fileName = "Generic_Template_Illinois.xls";
                  string fullFileName = FileUtil.GetFileFullPath(pricingRequestDir, fileName);

                  FileStream fileStream = new FileStream(fullFileName, FileMode.CreateNew);

                  const int size = 4096;
                  byte[] bytes = new byte[4096];
                  int numBytes;
                  while((numBytes = resourceStream.Read(bytes, 0, size)) > 0)
                  {
                        fileStream.Write(bytes, 0, numBytes);
                  }

                  resourceStream.Close();
                  fileStream.Close();
Why cannot you put this file one folder below the root folder and use it when required?

--Nauman
For a couple of reasons:
1) It's bad form to mix your reference files with with your .aspx files
2) Deployment is made more difficult - this solution will be re-used over and over in different environments, so I utiilize nant scripts to run deployment (just another one-off to worry about when moving solutions)
3) We have a reference folder for this kind of stuff, but it only contains assemblies and I'd hate to just throw it in there
Thanks for all the help everyone - I've posted my results below:

// extract the file from the resource library
                  string genericTemplateDir = EnvironmentHandler.Instance.ActiveEnvironment.EnvironmentSettings.GetSettingValue("GenericTemplateDirectory");
                  FileUtil.EnsureDirectoryExists(genericTemplateDir);

                  // Get embedded resource stream.
                  // See this class library project for the Generic_Template_Illinois.xls resource
                  Assembly assembly = Assembly.Load("DirectEnergy.Cmt.Illinois.Adapter");
                  string[] assemblyNameParts = assembly.FullName.Split(',');
                  Stream resourceStream = assembly.GetManifestResourceStream(assemblyNameParts[0] + ".Generic_Template.xls");

                  string fileName = "Generic_Template.xls";
                  string fullFileName = FileUtil.GetFileFullPath(genericTemplateDir, fileName);

                  // Delete the file if it exists to ensure latest and greatest is available
                  if(File.Exists(fullFileName))
                  {
                        File.Delete(fullFileName);
                  }

                  FileStream fileStream = new FileStream(fullFileName, FileMode.Create);

                  const int size = 4096;
                  byte[] bytes = new byte[4096];
                  int numBytes;
                  while((numBytes = resourceStream.Read(bytes, 0, size)) > 0)
                  {
                        fileStream.Write(bytes, 0, numBytes);
                  }
                  
                  resourceStream.Close();
                  fileStream.Close();

                  Response.Clear();
                  Response.AddHeader("Content-Disposition","attachment; FileName=" + fileName.ToString());
                  Response.CacheControl = "private";
                  Response.ContentType = "application/vnd.ms-excel";
                  FileStream httpFileStream = File.Open(fullFileName,FileMode.Open);
                  byte[] byteArray = new byte[httpFileStream.Length];
                  httpFileStream.Read(byteArray,0,byteArray.Length);
                  httpFileStream.Close();
                  Response.BinaryWrite(byteArray);