Any info on the chinese '360 secure browser'? Having issues with it downloading files I am streaming - asp.net

There is a desktop browser called '360 secure browser'. They have a fairly large share of the market in China, and we are required to support them.
It says the layout engine is Trident (IE), which is what I expected, but I can't verify that right now (on a mac!).
The reason for this is that I have some forms that kick off a download, streaming bytes to the client, and they work in the other major browsers. The code that causes the issue is below, or similar. Is this doing something wrong that I don't notice? The byte streams are usually on the order of 50-100KB, and we haven't had issues with it yet.
This code is called in response to a PostBack event (eg, button click in a grid, etc)
This function is called with bytestreams from files, generated in memory, or read from db.
The function:
public static bool DownloadStream(byte[] packageStream, string fileName) {
var response = HttpContext.Current.Response;
response.Clear();
response.AddHeader("Accept-Ranges", "bytes");
response.AddHeader("Content-Disposition", "inline; filename=" + HttpUtility.UrlEncode(fileName, Encoding.UTF8));
response.AddHeader("Content-Length", packageStream.Length.ToString());
response.ContentType = "application/xlsx";
response.BinaryWrite(packageStream);
response.Flush();
HttpContext.Current.ApplicationInstance.CompleteRequest();
return true;
}
Does anyone have any experience supporting this browser? I can't find any information on it when searching in english on google. No specs, no docs, nothing. I have to go to Baidu to find info, and I can't read that level of chinese!
EDIT:
The issue is with the downloader that 360 uses, apparently. I would like to know if there is something that should be changed in the streaming code, though. A header that I am missing, or something else.
This is only happening for small files. Same page, bigger download = no issues.
Changing to the built-in IE downloader causes the issue to go away.

Hi i tried your code on 360 secure browser. it work for me. and i edit a little bit below is my code.
Note: As i know, 360 secure browser is using IE Core.
protected void Page_Load(object sender, EventArgs e)
{
DownloadStream(StreamFile(#"C:\Users\My\Desktop\test2.xlsx"), "test.xlsx");
}
private byte[] StreamFile(string filename)
{
FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
// Create a byte array of file stream length
byte[] Data = new byte[fs.Length];
//Read block of bytes from stream into the byte array
fs.Read(Data, 0, System.Convert.ToInt32(fs.Length));
//Close the File Stream
fs.Close();
return Data; //return the byte data
}
public static bool DownloadStream(byte[] packageStream, string fileName)
{
var response = HttpContext.Current.Response;
response.ClearContent();
response.ClearHeaders();
response.AppendHeader("Accept-Ranges", "bytes");
response.AppendHeader("Content-Disposition", "inline; filename=" + HttpUtility.UrlEncode(fileName, Encoding.UTF8));
response.AppendHeader("Content-Length", packageStream.Length.ToString());
response.ContentType = "application/xlsx";
response.BinaryWrite(packageStream);
response.Flush();
response.End();
return true;
}

Related

Response.Redirect is not working

i am writing a code where after clicking one button one page will be redirected to another nd after opening 2nd page one pdf file will be download just like this website http://www.findwhitepapers.com/content22881 .But instead of opening the 2nd page and downloading the pdf file only pdf file is downloaded but 2nd page is not opening.1st page code is
protected void Button1_Click(object sender, EventArgs e)
{
Response.Redirect("2nd.aspx");
}
2nd page's code is written below.
protected void Page_Load(object sender, EventArgs e)
{
string filepath = "guar-gum/Guar-gum-export-report.pdf";
// The file name used to save the file to the client's system..
string filename = Path.GetFileName(filepath);
System.IO.Stream stream = null;
try
{
// Open the file into a stream.
stream = new FileStream(Server.MapPath("Guar-gum-export-report.pdf"), System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read);
// Total bytes to read:
long bytesToRead = stream.Length;
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment; filename=" + filename);
// Read the bytes from the stream in small portions.
while (bytesToRead > 0)
{
// Make sure the client is still connected.
if (Response.IsClientConnected)
{
// Read the data into the buffer and write into the
// output stream.
byte[] buffer = new Byte[10000];
int length = stream.Read(buffer, 0, 10000);
Response.OutputStream.Write(buffer, 0, length);
Response.Flush();
// We have already read some bytes.. need to read
// only the remaining.
bytesToRead = bytesToRead - length;
}
else
{
// Get out of the loop, if user is not connected anymore..
bytesToRead = -1;
}
}
Response.Flush();
}
catch (Exception ex)
{
Response.Write(ex.Message);
// An error occurred..
}
finally
{
if (stream != null)
{
stream.Close();
//
}
}
}
What do you expect to see on the 2nd page? All you have there is a pdf file. Do you expect an empty page?
Your redirect works fine. When you click the button a PDF file will be sent back to the browser and it will see it as a file that should be downloaded. No page will be sent to the browser so there is no page to see.
Here is the solution:
Don't code what you have done in page2.aspx for file downloading instead put an iframe in the page2.aspx and set the src to the file Url.
I guess it is guar-gum/Guar-gum-export-report.pdf in your case. May be you should change this to start from root of the site by prefix / to the file url.
Put this in page2.aspx
<iframe width="1" height="1" frameborder="0" src="[File location]"></iframe>
It is very simple way and No redirects or JavaScript and your Page2.aspx will also open.
UPDATE
Based on the comments below this answer
I think there is no better solution but here is another mindbending one (psst! hope you and other like..) move the page2.aspx code one for file download ONLY to the third page page3.aspx and set iframe.src to page3.aspx
Reference
SO - How to start automatic download of a file in Internet Explorer

How to do httpPost to a webservice which accepts a byte array of a file using c#

I am working on an API kind of project,
I have wrote a WebMethod (not exactly. I am using MVC to create REST like API)
public UploadFileImage(string employeeId, byte[] imageBytes, string imageName)
{
// saves the imagebyte as an image to a folder
}
the web service would be consumed by a web app, or windows or even iphone or such portable stuffs. I am testing my web service using a web app, by simple httpPost.
string Post(Uri RequestUri, string Data)
{
try
{
HttpWebRequest request = HttpWebRequest.Create(RequestUri) as HttpWebRequest;
request.Method = "POST";
request.ContentType = IsXml.Checked ? "text/xml" : "application/x-www-form-urlencoded";
byte[] bytes = Encoding.ASCII.GetBytes(Data);
Stream os = null; // send the Post
request.ContentLength = bytes.Length; //Count bytes to send
os = request.GetRequestStream();
os.Write(bytes, 0, bytes.Length);
HttpWebResponse httpWebResponse = (HttpWebResponse)request.GetResponse();
StreamReader streamReader = new StreamReader(request.GetResponse().GetResponseStream());
return streamReader.ReadToEnd();
}
catch (Exception ex)
{
return ex.Message;
}
}
This code works fine for evey method like, AddEmployee, DeleteEmployee etc. THe parameter Data is of form "Id=123&name=abcdefgh&desig=Developer",
How I call any other function is
Post(new Uri("http://localhost/addemployee"),"name=abcd&password=efgh")
where post is the function i wrote.
All good for all functions. Except that I dont know how to consume the above mentioned function UploadFileImage to upload an image?
Thanks
Try encoding the imageBytes as Base64.
From your code snippet is not too clear how you call UploadFileImage, that is how you convert its parameters tripplet into Data.
That is why my answer is quite generic:
In general, you'd better transfer your image file by
request.ContentType = "multipart/form-data; boundary=----------------------------" + DateTime.Now.Ticks.ToString("x");
Please allow me to refer you to a sample at StackOverflow on how to format a multipart request. I am sure that if you google, you shall find a lots of detailed examples and explanations as well.
I hope this helps :-)

How to handle errors when using ASP.NET to create a zipfile for download?

I'm working on a functionality in my asp.net web site that enables the user to download some files as a zip file. I'm using the DotNetZip library to generate the zip file.
My code looks like this:
protected void OkbtnZipExport_OnClickEvent(object sender, EventArgs e)
{
var selectedDocumentIds = GetSelectedDocIds();
string archiveName = String.Format("archive-{0}.zip", DateTime.Now.ToString("yyyy-MMM-dd-HHmmss"));
AddResponseDataForZipFile(Response, archiveName);
try
{
string errorMessage = Utils.ExportToZip(selectedDocumentIds, arkivdelSearchControl.GetbraArkivConnection(), Response.OutputStream);
if (!string.IsNullOrEmpty(errorMessage))
{
LiteralExportStatus.Text = errorMessage;
}
else
LiteralExportStatus.Text = "Success";
}
catch (Exception ex)
{
LiteralExportStatus.Text = "Failure " + ex.Message;
}
Response.Flush();
Response.Close();
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
private void AddResponseDataForZipFile(HttpResponse response, string zipName)
{
Response.Clear();
Response.BufferOutput = false;
Response.ContentType = "application/x-zip-compressed";
Response.AddHeader("content-disposition", "attachment; filename=" + zipName);
Response.AddHeader("Expires", "0");
Response.AddHeader("Content-Description", "Zip Arcive");
}
Now, if anything goes wrong, say the Utils.ExportToZip method fails, I want to present an error message to the user and not the download dialog. Do I have to remove some data from the Response object in order to cancel the download operation?
Best regards
OKB
first, Don't call HttpContext.Current.ApplicationInstance.CompleteRequest();
Reference.
At one point, there was some example code that showed CompleteRequest(), but it's wrong.
Second - to do what you describe,
you'll need to insure that the zip file can be created correctly and in its entirety, before sending anything. That means you should do the AddResponseDataForZipFile() only after the zipfile is completely created. That means you need to create an actual zip file on the server, and not simply save out to Response.OutputStream. Once the file is successfully created, then call AddResponseDataForZipFile(), stream the bytes for the temp zip file, call Response.Close(), then delete the temporary zip file.
I can't comment at the moment, so take this answer as one.
How does Utils.ExportToZip work?
If the reason it takes the Response.OutputStream for the constructor is to write the zip-file directly into it, then you need to set Buffering in order to "undo" that in your AddResponseDataForZipFile Method:
Response.BufferOutput = true;

ASP.NET show PDF file to user instead of "save as" dialog

My ASP.NET application return PDF file to user using code below
Context.Response.Clear();
Context.Response.ContentType = "application/pdf";
Context.Response.TransmitFile(optionEntityCmd.PathToSave);
Context.Response.End();
This code show Save As browser dialog, is it possible instead of Save As dialog load PDF file directly in browser?
You could append the Content-Disposition header:
Context.Response.AppendHeader(
"Content-Disposition",
"inline; filename=foo.pdf"
);
Is it a dynamically created file? If not, you can just hyperlink or Response.Redirect to it I believe.
I do not know for sure for classic asp.net but using mvc, streaming it to the user does what you want:
MemoryStream stream = PDF.GeneratePDFByStream();
stream.Flush(); //Always catches me out
stream.Position = 0; //Not sure if this is required
return stream;
with
public static MemoryStream GeneratePDFByStream() {
var doc1 = new Document();
//use a variable to let my code fit across the page...
string path = AppDomain.CurrentDomain.BaseDirectory + "PDFs";
MemoryStream stream = new MemoryStream();
PdfWriter writer = PdfWriter.GetInstance(doc1, stream);
writer.CloseStream = false;
// Actual Writing
doc1.Open();
// writing comes here, you will probably just load the PDF in a stream?
doc1.Close();
return stream;
}
And your MVC controller returns something like
return File(GetPDFStream(id), "application/pdf");
So, I know this is not the exact answer you are looking for, but maybe you should try to stream your PDF to the user as it will open it in a new tab as far as I ever tested it.
From the top of my head, you should get something like:
Response.Clear();
Response.ContentType = "application/pdf";
Response.OutputStream.Write( objMemoryStream.ToArray(), 0,
Convert.ToInt32(objMemoryStream.Length));
Response.Flush();
try { Response.End(); } catch{}

How to Download A file stored in SQL DB in Binary Format

I am simply storing uploaded file into a binary field in SQL Server but I also need to allow users to download it with Asp.NET. How can I do that ?
Thanks in advance.
Here's a Microsoft Knowledge Base article on this.
How to retrieve the file from your database depends on the data access technology you use; I will just assume that you have some Byte array data containing the file (e.g. by filling a DataSet and accessing the field) and some string filename.
Response.Clear()
Response.ContentType = "application/octet-stream"
Response.AddHeader("Content-Disposition", "attachment;filename=""" & filename & """")
Response.BinaryWrite(data)
Response.End()
Put the above code in some download.aspx and link to this file. You probably want to pass some query string information to your download.aspx, so that your code knows which file to get from the database.
Read the data into a filestream object with the appropriate extension tacked on to it, and have the user download the resulting file.
You'll want to use the System.IO BinaryWriter object on the filestream to create the file...something like this:
FileStream fs = new FileStream("thisfile.bin", FileMode.Create);
binWriter= new BinaryWriter(fs);
binWriter.Write(varHoldingSqlRetrievedBinaryData);
Add a Generic Handler (.ashx) page to your web site. The ashx code body below demonstrates how to read an arbitrary stream (in this case a PNG file from disk) and write it out in the response:
using System;
using System.Web;
using System.IO;
namespace ASHXTest
{
public class GetLetter : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
// Get letter parameter from query string.
string fileName = context.Request.MapPath(string.Format("{0}.png",
context.Request.QueryString["letter"]));
// Load file from disk/database/ether.
FileStream stream = new FileStream(fileName, FileMode.Open,
FileAccess.Read);
byte[] buffer = new byte[stream.Length];
stream.Read(buffer, 0, buffer.Length);
stream.Close();
// Write response headers and content.
context.Response.ContentType = "image/png";
context.Response.OutputStream.Write(buffer, 0, buffer.Length);
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
If desired, you can also set the Content-Disposition header as demonstrated in Heinzi's answer:
context.Response.AddHeader("Content-Disposition",
"attachment;filename=\"letter.png\"");

Resources