Calling Generic Handler .ashx from asp.net code behind - asp.net

I have a generic handler (.ashx) which is used to download an excel file.
When I try to call it using the code below:
HttpWebRequest request = WebRequest.Create("ExcelDownload.ashx?id=123") as HttpWebRequest;
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
the file is not downloaded.But,I am able to debug the handler code when the request is made.
But when the handler is used in the anchor tags,I am able to download the file.
Excel Download
Any idea why the first option is not working?
Additional Comments:
In the handler,I am using the below code which works fine with anchor tag.
I am not doing any thing with the response object returned by the request.
context.Response.Clear();
context.Response.ClearContent();
context.Response.ClearHeaders();
context.Response.Buffer = true;
byte[] buffer = memoryStream.ToArray();
context.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
context.Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", faWorkbookFileName));
context.Response.BinaryWrite(buffer);
context.Response.End();

Related

Need to read a URL and save the response as a file on the same server in ASP.NET

I need to have a page on my website that when opened will read another URL address and capture the response from it (it's actually XML data responding) and then save that data on that same webservr to a file called DATA.XML
It needs to overwrite any file that is already there.
I only have ASP.NET available to me as a progrmming language.
Can someone show me how to do this in a ASP page.
so something like?
Get the response from the other URL in to strResult.
WebResponse objResponse;
WebRequest objRequest = HttpWebRequest.Create(strURL);
objResponse = objRequest.GetResponse();
using (StreamReader sr = new StreamReader(objResponse.GetResponseStream()))
{
strResult = sr.ReadToEnd();
sr.Close();
}
return strResult;
Use System.IO to save the strResult to a file (you can look that up as its pretty common code)

How to write the context of a FileStream to my ASP.net HTTP Response?

Suppose that I want my ASP.net web server to open a file and then send it to the browser.
First, I write this:
FileInfo file = new System.IO.FileInfo(#"\\myshare\myfile.zip");
FileStream fileStream = file.Open(FileMode.Open, FileAccess.Read, FileShare.Read);
What comes next?
I would think something along the lines of Response.Write(..., but I'm having trouble figuring it out.
straight from MSDN:
HttpResponse.BinaryWrite Method
FileStream MyFileStream;
long FileSize;
MyFileStream = new FileStream("sometext.txt", FileMode.Open);
FileSize = MyFileStream.Length;
byte[] Buffer = new byte[(int)FileSize];
MyFileStream.Read(Buffer, 0, (int)FileSize);
MyFileStream.Close();
Response.Write("<b>File Contents: </b>");
Response.BinaryWrite(Buffer);
Edit: of course there are also many other methods, like streaming which allows you to never allocate the byte[] buffer all at once on the web server. This was just a starting point...
A good way to send files is using the content-disposition header before you send the actual raw data
for instance:
Response.ContentType = "application/jpeg";
Response.AddHeader("content-disposition", "attachment; filename=" + fileName);
Response.WriteFile(path);
Response.End();
where fileName is just the filename (with extension)
and path is the full path to the file

Asp.net Webservice returning docx file

I have some xml data. I've made an asp.net soap based webservice that takes the xml as a byte buffer applies xsl transformation to it and converts it to a docx file. But when i return the docx file using the response object i get an error that client found response of type application/vnd-word but it was expecting text/xml.
Service Snippet to push document file after xsl transformation
Context.Response.Clear();
Context.Response.ClearHeaders();
Context.Response.ContentType = "application/vnd.openxmlformats- officedocument.wordprocessingml.document";
Context.Response.AddHeader("Content-Disposition", "attachment; filename=" + "test.docx");
Context.Response.Flush();
Context.Response.End();
Is this via a webservice call? If you are calling via a webservice proxy client, then it is expecting a SOAP response and not a binary stream. You will need to model a SOAP-compatible response which the caller can understand.
Setting the content-type and content-disposition enables a browser to do the "right" thing (ie open the file-save dialog) but custom clients (httpwebclient, web service proxy, etc) don't have those behaviors built-in so you will need to add whatever is missing.
Where are you actually writing the data?
oh and try this... (if your .docx is a well formed office openxml file)
Response.Clear();
Response.ContentType = "application/msword";
Response.AppendHeader("Content-Type", "application/msword");
Response.AppendHeader("Content-disposition", String.Format("attachment; filename={0}", FileName));
Response.BinaryWrite(DataBytes);
Response.End();
Response.Flush();
Context.Response.Clear();
Context.Response.ContentType = "application/msword";
Context.Response.AddHeader("Content-Type", "application/msword");
Context.Response.AddHeader("Content-Disposition", "attachment; filename=" + "test.docx");
Context.Response.End();
Context.Response.Flush();

asp.net ashx handler prompting download instead of displaying file

I implemented a generic handler in my application which works great for images, but when I manually type the handler URL in the browser with the image's querystring it prompts download instead of displaying. Here is my code:
public void ProcessRequest(HttpContext context)
{
if (this.FileName != null)
{
string path = Path.Combine(ConfigurationManager.UploadsDirectory, this.FileName);
if (File.Exists(path) == true)
{
FileStream file = new FileStream(path, FileMode.Open);
byte[] buffer = new byte[(int)file.Length];
file.Read(buffer, 0, (int)file.Length);
file.Close();
context.Response.ContentType = "application/octet-stream";
context.Response.AddHeader("content-disposition", "attachment; filename=\"" + this.FileName + "\"");
context.Response.BinaryWrite(buffer);
context.Response.End();
}
}
}
I am using the octet-stream because I'm dealing with more than just images and I don't always know the content type of the file. Thanks in advance!
The only way is to specify correct ContentType so the browser know what to do with receiving file, depending on installed plugins (for example, view pdf files in browser frame) and system assosiations (for example, offer to open document in MS Office instead of simple download)
You can try to specify Content Type depending on file extension, i.e.:
if(Path.GetExtension(path) == ".jpg")
context.Response.ContentType = "image/jpeg";
else
context.Response.ContentType = "application/octet-stream";
If you store the ContentType as part of the files metadata, when you pull it back down your could use it.
theFile = GetFile(id)
context.Response.ContentType = theFile.Type;
The content-disposition header is the one that causes your browser to show the download dialog. Remove that line and it will show in the browser.

ASP.NET stream content from memory and not from file

The users have requested the option to "download" a csv file representation of GridView contents. Does anyone know how to do this without saving the file to the server but rather just streaming it to the user from memory?
Thanks
Implement an IHttpHandler.
I used something similar to the following in the ProcessResponse for outputing a CSV that had previously been constructed in a database table...
public void ProcessRequest(HttpContext context)
{
HttpResponse response = context.Response;
HttpRequest request = context.Request;
//Get data to output here...
//Turn off Caching and enforce a content type that will prompt to download/save.
response.AddHeader("Connection", "close");
response.AddHeader("Cache-Control", "private");
response.ContentType = "application/octect-stream";
//Give the browser a hint at the name of the file.
response.AddHeader("content-disposition", string.Format("attachment; filename={0}", _filename));
//Output the CSV here...
foreach(BatchDTO.BatchRecordsRow row in dtoBatch.BatchRecords)
response.Output.WriteLine(row.Data);
response.Flush();
response.Close();
}
There are a number of libraries that make generating a CSV easier, you should just be able to pass it the Response.OutputStream to have it write to there rather than to a file stream.
Use context.Response.OutputStream.
Here's an example.
I created a StringBuilder and dump the contents to the Response object using the following code ("csv" is the StringBuilder variable).
Response.ContentType = #"application/x-msdownload";
Response.AppendHeader("content-disposition", "attachment; filename=" + FILE_NAME);
Response.Write(csv.ToString());
Response.Flush();
Response.End();
I have used the RKLib export library a few times to great effect, this uses a memory stream and can be given any datatable which it will export as a csv download:
http://www.codeproject.com/KB/aspnet/ExportClassLibrary.aspx

Resources