Error Downloading .apk from Asp.net website using android phone browser - c#

In my .aspx page, I have download button which onclick download the .apk file.
When I run on my pc it works fine .apk file gets downloaded on my pc. But when I use my android phone go to that site and click download button it will start downloading but file click gives error There is a problem parsing the package.
Also actual file size is 604kb (while downloading from andorid phone gives 22kb)
The downloaded file(22kb) contain html content.
private void DownloadFile()
{
string getPath = "demo_Android/demoAndroid.apk";
System.IO.Stream iStream = null;
// Buffer to read 10K bytes in chunk:
byte[] buffer = new Byte[1024];
// Length of the file:
int length;
// Total bytes to read:
long dataToRead;
// Identify the file to download including its path.
string filepath = Server.MapPath(getPath);
// Identify the file name.
string filename = System.IO.Path.GetFileName(filepath);
try
{
// Open the file.
iStream = new System.IO.FileStream(filepath, System.IO.FileMode.Open,
System.IO.FileAccess.Read, System.IO.FileShare.Read);
// Total bytes to read:
dataToRead = iStream.Length;
Response.ContentType = "application/vnd.android.package-archive";
Response.AddHeader("Content-Disposition", "attachment; filename=" + filename);
// Read the bytes.
while (dataToRead > 0)
{
// Verify that the client is connected.
if (Response.IsClientConnected)
{
// Read the data in buffer.
length = iStream.Read(buffer, 0, 1024);
// Write the data to the current output stream.
Response.OutputStream.Write(buffer, 0, length);
// Flush the data to the HTML output.
Response.Flush();
buffer = new Byte[1024];
dataToRead = dataToRead - length;
}
else
{
//prevent infinite loop if user disconnects
dataToRead = -1;
}
}
}
catch (Exception ex)
{
// Trap the error, if any.
Response.Write("Error : " + ex.Message);
}
finally
{
if (iStream != null)
{
//Close the file.
iStream.Close();
}
Response.Close();
}
}

Heres how i fixed my problem
My Application is hosted under Window server 2008r2 having IIS 7
Step 1: In .aspx page add hyperlink set navigateurl as file path
<asp:HyperLink ID="lnkdwnload" runat="server" NavigateUrl="~/Application_Android/MyAndroidAppAame.apk">Download MyApp</asp:HyperLink>
Step 2: Web.config add mimeMap element under staticContent
<system.webServer>
<staticContent>
<mimeMap fileExtension=".apk" mimeType="application/vnd.android.package-archive"/>
</staticContent>
</system.webServer>

This could be the same problem I've also faced with Android's native browser. Thing is that the download action is being passed to the platform's download application (separate from the browser) which reloads the page and instead of the real APK, it downloads the aspx page.
Try downloading with Opera Mobile. If the problem goes away, it's most probably the same problem. Replacing the button with a standard hyperlink would be the simplest solution to this. Though it might not be an option if you need to have other logic there aswell instead of just downloading.

Related

Uploading media files to Azure File Share over 4 MB corrupts them

I'm trying to upload large files to Azure File Share via the Azure.Storage.Files.Shares library and am I running into corruption issues on all media files (images, PDFs, etc) over ~4 MB. Azure File Share has a limit of 4 MB for a single request which is why I've split the upload in to multiple chunks, but it still corrupts the files despite every chunk upload returning a 201.
Notes:
It doesn't seem like it's an issue with having to write multiple chunks as I can write a 3 MB file in as many chunks as I want and it will be totally fine
.txt files over 4 MB have no issues and display totally fine after uploading
This uploading portion of this function is basically copied/pasted from the only other stack overflow "solution" I found regarding this issue:
public async Task WriteFileFromStream(string fullPath, MemoryStream stream)
{
// Get pieces of path
string dirName = Path.GetDirectoryName(fullPath);
string fileName = Path.GetFileName(fullPath);
ShareClient share = new ShareClient(this.ConnectionString, this.ShareName);
// Set position of the stream to 0 so that we write all contents
stream.Position = 0;
try
{
// Get a directory client for specified directory and create the directory if it doesn't exist
ShareDirectoryClient directory = share.GetDirectoryClient(dirName);
directory.CreateIfNotExists();
if (directory.Exists())
{
// Get file client
ShareFileClient file = directory.GetFileClient(fileName);
// Create file based on stream length
file.Create(stream.Length);
int blockSize = 300 * 1024; // can be anything as long as it doesn't exceed 4194304
long offset = 0; // Define http range offset
BinaryReader reader = new BinaryReader(stream);
while (true)
{
byte[] buffer = reader.ReadBytes(blockSize);
if (buffer.Length == 0)
break;
MemoryStream uploadChunk = new MemoryStream();
uploadChunk.Write(buffer, 0, buffer.Length);
uploadChunk.Position = 0;
HttpRange httpRange = new HttpRange(offset, buffer.Length); // offset -> buffer.Length-1 (inclusive)
var resp = file.UploadRange(httpRange, uploadChunk);
Console.WriteLine($"Wrote bytes {offset}-{offset+(buffer.Length-1)} to {fullPath}. Response: {resp.GetRawResponse()}");
offset += buffer.Length; // Shift the offset by number of bytes already written
}
reader.Close();
}
else
{
throw new Exception($"Failed to create directory: {dirName}");
}
}
catch (Exception e)
{
// Close out memory stream
throw new Exception($"Error occured while writing file from stream: {e.Message}");
}
}
Any help on this is greatly appreciated.

ZipArchive serves up invalid file on live server

I am using ZipArchive with in a handler to serve to a user using memory stream and a web handler. Locally this was working until I uploaded the application to a live site.
Here is my code.
using (ZipArchive newArchive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
{
newArchive.CreateEntryFromFile(fileName, Path.GetFileName(fileName));
if (File.Exists(acRefFile))
{
newArchive.CreateEntryFromFile(acRefFile,
newACRefName + Path.GetExtension(acRefFile));
}
else
{
SystemLogManager sysLogMgr = new SystemLogManager();
sysLogMgr.AddErrorMessage(acRefFile, "File not found");
}
if (File.Exists(exRefFile))
{
newArchive.CreateEntryFromFile(exRefFile,
newExRefName + Path.GetExtension(exRefFile));
}
else
{
SystemLogManager sysLogMgr = new SystemLogManager();
sysLogMgr.AddErrorMessage(exRefFile, "File Not Found");
}
if (File.Exists(exRef2File))
{
newArchive.CreateEntryFromFile(exRef2File,
newExRef2Name + Path.GetExtension(exRef2File));
}
}
memoryStream.Position = 0;
byte[] bytes = memoryStream.GetBuffer();
context.Response.Buffer = true;
context.Response.Clear();
context.Response.ContentType = "application/zip";
context.Response.AddHeader("content-disposition",
string.Format("attachment; filename =app_{0}_{1}.zip", appForm.Cand_sno,
appForm.App_year));
context.Response.BinaryWrite(bytes.ToArray());
context.Response.Flush();
And the following image shows the downloaded zip file and the error generated.
So is there anything in code that could be wrong or something I could try server side?
Update 1:
Based on the comments received I tried adding the zip file directly onto the server. Same issue occurs as in the zip is 'corrupted'.
Update 2:
Further investigations I have now discovered that the zip file opens up when using 7zip but not standard windows extract. When right click extract all the message states the zip is empty.
Thanks
So the fix for this question was simply to change the byte[] bytes = MemoryStream.GetBuffer(); to byte[] bytes = MemoryStream.ToArray(); What this does is only get the used bytes not the extra bytes the buffer adds.
I use ZipFile class and the result is never corrupted.
Can you try this?
ZipFile.CreateFromDirectory("C:\somefolder", "C:\someotherfolder\somefile.zip");

Trouble with getting file from dropbox and saving on my server

Here is my java script code to choose file from dropbox, When I try to save this file to server using C# I am able to see file on server but it is empty.when I am trying to open file the file is giving error like 'file is corrupted'. using signalR.
options = {
// Required. Called when a user selects an item in the Chooser.
success: function (files) {
alert("Here's the file link: " + files[0].link)
hub.server.servermethod(files[0].link, files[0].name);
},
// Optional. Called when the user closes the dialog without selecting a file
// and does not include any parameters.
cancel: function () {
},
// Optional. "preview" (default) is a preview link to the document for sharing,
// "direct" is an expiring link to download the contents of the file. For more
// information about link types, see Link types below.
linkType: "preview", // or "direct"
// Optional. A value of false (default) limits selection to a single file, while
// true enables multiple file selection.
multiselect: false, // or true
// Optional. This is a list of file extensions. If specified, the user will
// only be able to select files with these extensions. You may also specify
// file types, such as "video" or "images" in the list. For more information,
// see File types below. By default, all extensions are allowed.
extensions: ['.csv', '.xls', '.tsv', '.xlsx', '.txt'],
};
var button = Dropbox.createChooseButton(options);
$('#container').append(button);
function some() {
Dropbox.choose(options);
}
server Method code is
// execute the request
HttpWebResponse response = (HttpWebResponse)
request.GetResponse();
// we will read data via the response stream
Stream resStream = response.GetResponseStream();
string tempString = null;
int count = 0;
Byte[] buffer = new Byte[32 * 1024];
StringBuilder sb = new StringBuilder();
do
{
// fill the buffer with data
count = resStream.Read(buffer, 0, buffer.Length);
// make sure we read some data
if (count != 0)
{
// translate from bytes to ASCII text
tempString = Encoding.ASCII.GetString(buffer, 0, count);
// continue building the string
sb.Append(tempString);
}
}
while (count > 0); // any more data to read?
using (FileStream fs = File.Create(System.Configuration.ConfigurationManager.AppSettings.GetValues("DocumentPath").First().ToString() + fileName))
{
// Byte[] bufer = new Byte[32 * 1024];
fs.Write(buffer, 0, buffer.Length);
}
You're setting linkType to "preview", which gives you a link to a preview page for the file, and not the file content itself. If you want direct access to the file content, e.g., to immediately and programmatically download the content to your server, as it seems you're trying to do, you should use the "direct" linkType.

Why is my StreamResult not returning the whole files?

I have to serve large files (200-800MB) to the client from my controller. I tested FileStreamResult, but this class buffered the whole file in memory. This behavior is not good enough for my project.
Further i testest the approach from here: http://support.microsoft.com/kb/812406. Concerning the memory, this looks pretty good -but the files are not completly downloaded on the client (the original file is 210222 KB, the downloaded ones are 209551 to 209776). This means there is about 0.5 MB lost (which concequently causes the files to be broken).
Has somebody an idea? Whats the best way to do this anyway? Im grateful for everything.
Just for users in the future, the link pointed to the following code:
System.IO.Stream iStream = null;
// Buffer to read 10K bytes in chunk:
byte[] buffer = new Byte[10000];
// Length of the file:
int length;
// Total bytes to read:
long dataToRead;
// Identify the file to download including its path.
string filepath = "DownloadFileName";
// Identify the file name.
string filename = System.IO.Path.GetFileName(filepath);
try
{
// Open the file.
iStream = new System.IO.FileStream(filepath, System.IO.FileMode.Open,
System.IO.FileAccess.Read,System.IO.FileShare.Read);
// Total bytes to read:
dataToRead = iStream.Length;
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment; filename=" + filename);
// Read the bytes.
while (dataToRead > 0)
{
// Verify that the client is connected.
if (Response.IsClientConnected)
{
// Read the data in buffer.
length = iStream.Read(buffer, 0, 10000);
// Write the data to the current output stream.
Response.OutputStream.Write(buffer, 0, length);
// Flush the data to the HTML output.
Response.Flush();
buffer= new Byte[10000];
dataToRead = dataToRead - length;
}
else
{
//prevent infinite loop if user disconnects
dataToRead = -1;
}
}
}
catch (Exception ex)
{
// Trap the error, if any.
Response.Write("Error : " + ex.Message);
}
finally
{
if (iStream != null)
{
//Close the file.
iStream.Close();
}
Response.Close();
}
Update
This is my action:
public DownloadResult TransferTest()
{
string fullFilePath = #"C:\ws\Test\Test\Templates\example.pdf";
return new DownloadResult(fullFilePath);
}
I simply call the action directly from my browser (http://xxx.xxx/Other/TransferTest).
The code basically looks sound - you are more-or-less correctly handling the return value from Read (if I was being picky, I would say check it for <=0, but this would not be an expected behavior since you probably have a lock on the file).
The only thing that occurs is: try adding a:
Response.OutputStream.Flush();
and perhaps:
Response.OutputStream.Close();
to make sure that the output stream is flushed.

Save Image From Webrequest in C#

I'm using a jQuery webcam plugin to communicate with a webcam in my page and take a snapshot. The way it works is by communicating with a Flash helper. To save the picture it takes the name of another page and sends a web request to that page. And I'm successfully receiving that request on the other. I want to save the image from that request.
You claim to have the code for getting the request, you just need to load the image and save it to disk. This needs cleaned up, but something like the following should work:
System.IO.Stream respStream = resp.GetResponseStream();
System.Drawing.Image img = System.Drawing.Image.FromStream(respStream );
img.Save(PathToSaveTo):
I Have Done That In This And It Works For Me.
protected void Page_Load(object sender, EventArgs e)
{
string strFile = DateTime.Now.ToString("dd_MMM_yymmss") + ".jpg";
FileStream log = new FileStream(Server.MapPath(strFile),
FileMode.OpenOrCreate);
byte[] buffer = new byte[1024];
int c;
while ((c = Request.InputStream.Read(buffer, 0, buffer.Length)) > 0)
{
log.Write(buffer, 0, c);
}
//Write jpg filename to be picked up by regex and displayed on flash html page.
Response.Write(strFile);
log.Close();
}

Categories

Resources