Not able to download file. Giving Exception - c#

I am trying to download multiple file in zip formate using zipOutputStream.
Its Giving Exception in blob.DownloadToStream(zipOutputStream); line
List<string> lstPath = DAL_AttachmentSQLHelper.GetAllAttachementPath(claimId);
CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));
var container = cloudStorageAccount.CreateCloudBlobClient().GetContainerReference("traveoappclaimattachments/Traveo1");
using (var zipOutputStream = new ZipOutputStream(System.Web.HttpContext.Current.Response.OutputStream))
{
foreach (var blobFileName in lstPath)
{
zipOutputStream.SetLevel(0);
var blob = container.GetBlockBlobReference(blobFileName);
var entry = new ZipEntry(blobFileName);
zipOutputStream.PutNextEntry(entry);
blob.DownloadToStream(zipOutputStream);
}
zipOutputStream.Finish();
zipOutputStream.Close();
}
System.Web.HttpContext.Current.Response.BufferOutput = false;
System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + "zipFileName.zip");
System.Web.HttpContext.Current.Response.ContentType = "application/octet-stream";
System.Web.HttpContext.Current.Response.Flush();
System.Web.HttpContext.Current.Response.End();

One problem that I see with your code is how you're creating an instance of CloudBlobContainer in your code. Assuming your container name is traveoappclaimattachments and all the files are located in Traveo1, you could try something like below:
List<string> lstPath = DAL_AttachmentSQLHelper.GetAllAttachementPath(claimId);
CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));
var container = cloudStorageAccount.CreateCloudBlobClient().GetContainerReference("traveoappclaimattachments");
using (var zipOutputStream = new ZipOutputStream(System.Web.HttpContext.Current.Response.OutputStream))
{
foreach (var blobFileName in lstPath)
{
zipOutputStream.SetLevel(0);
var blob = container.GetBlockBlobReference("Traveo1/" + blobFileName);
var entry = new ZipEntry(blobFileName);
zipOutputStream.PutNextEntry(entry);
blob.DownloadToStream(zipOutputStream);
}
zipOutputStream.Finish();
zipOutputStream.Close();
}
System.Web.HttpContext.Current.Response.BufferOutput = false;
System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + "zipFileName.zip");
System.Web.HttpContext.Current.Response.ContentType = "application/octet-stream";
System.Web.HttpContext.Current.Response.Flush();
System.Web.HttpContext.Current.Response.End();

Related

Download multiple file from blob as Zip folder

My files are in blob storage.So how i can download the multiple files from folder as zip
I am trying this code from some time it is working but not giving me output.Means its not starting the zip download.:
string zipFileName = "MyZipFiles.zip";
using (var zipOutputStream = new
ZipOutputStream(HttpContext.Current.Response.OutputStream))
{
zipOutputStream.SetLevel(0);
HttpContext.Current.Response.BufferOutput = false;
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + zipFileName);
HttpContext.Current.Response.ContentType = "application/zip";
foreach (var filePath in fileUrl)
{
var filename = Path.GetFileName(filePath.filename);
var filebytes = filePath.filebyte.BlobByteArray;
var fileEntry = new ZipEntry(Path.GetFileName(filePath.filename))
{
Size = filebytes.Length
};
zipOutputStream.PutNextEntry(fileEntry);
zipOutputStream.Write(filebytes, 0, filebytes.Length);
}
zipOutputStream.Flush();
zipOutputStream.Close();
}
My file url contains:
foreach (var item in obj)
{
em = new FileUrlForbyte();
em.filename = item.FileName;
em.url = objBlobHelper.GetFileByFileNameMultiple(item.ContainerName, item.SubFolderName + "/" + item.FileName, DateTime.Now.AddMinutes(2));
em.filebyte = objBlobHelper.DownloadFileByFileNameForAdobe(item.ContainerName, item.SubFolderName + "/" + item.FileName);
fileUrl.Add(em);
}
FOr more clarity:filePath contains:filename,fileurl and file byte:
[Route("api/Blob/getMultipleFileFromBlobByURI")]
[HttpGet]
public System.Web.Mvc.FileResult getMultipleFileFromBlobByURI(string containerName)
{
List<BlobStorageModel> obj = new JavaScriptSerializer().Deserialize<List<BlobStorageModel>>(containerName);
try
{
BlobHelper objBlobHelper = new BlobHelper(apiPrincipal);
List<FileUrlForbyte> fileUrl = new List<FileUrlForbyte>();
FileUrlForbyte em = new FileUrlForbyte();
foreach (var item in obj)
{
em = new FileUrlForbyte();
em.filename = item.FileName;
em.url = objBlobHelper.GetFileByFileNameMultiple(item.ContainerName, item.SubFolderName + "/" + item.FileName, DateTime.Now.AddMinutes(2));
em.filebyte = objBlobHelper.DownloadFileByFileNameForAdobe(item.ContainerName, item.SubFolderName + "/" + item.FileName);
fileUrl.Add(em);
}
// Here we will create zip file & download
string zipFileName = "MyZipFiles.zip";
var fileName = string.Format("{0}_ImageFiles.zip", DateTime.Today.Date.ToString("dd-MM-yyyy") + "_1");
var tempOutPutPath = System.Web.HttpContext.Current.Server.MapPath(Url.Content("/TempImages/")) + fileName;
try
{
using (var zipOutputStream = new ZipOutputStream(HttpContext.Current.Response.OutputStream))
{
zipOutputStream.SetLevel(9);
byte[] buffer = new byte[4096];
HttpContext.Current.Response.BufferOutput = false;
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + zipFileName);
HttpContext.Current.Response.ContentType = "application/zip";
foreach (var filePath in fileUrl)
{
var filename = Path.GetFileName(filePath.filename);
var filebytes = filePath.filebyte.BlobByteArray;
var fileEntry = new ZipEntry(Path.GetFileName(filePath.filename))
{
Size = filebytes.Length
};
zipOutputStream.PutNextEntry(fileEntry);
zipOutputStream.Write(filebytes, 0, filebytes.Length);
}
zipOutputStream.Finish();
zipOutputStream.Flush();
zipOutputStream.Close();
}
byte[] finalResult = System.IO.File.ReadAllBytes(tempOutPutPath);
if (System.IO.File.Exists(tempOutPutPath))
System.IO.File.Delete(tempOutPutPath);
if (finalResult == null || !finalResult.Any())
throw new Exception(String.Format("No Files found with Image"));
return new System.IO.File(finalResult, "application/zip", fileName);
}
catch (Exception)
{
throw;
}
}
catch (Exception)
{
throw;
}
}
Thanks #Sudheer for your inputs in the comments.
I am trying this code from some time it is working but not giving me output.Means its not starting the zip download.: string zipFileName = “MyZipFiles.zip”;
Referring to the above comment I have tried the below code and was able to execute it successfully.
CloudStorageAccount storage_Account = CloudStorageAccount.Parse(storageAccount_connectionString);
CloudBlobClient blob_Client = storage_Account.CreateCloudBlobClient();
CloudBlobContainer container = blob_Client.GetContainerReference(container_Name);
CloudBlockBlob cloudBlockBlob = container.GetBlockBlobReference(filename);
Stream file = File.OpenWrite(#"C:\Tools\" + filename);
cloudBlockBlob.DownloadToStream(file);
Console.WriteLine("Download completed!");
Then, I have created a container in my storage account as shown below.
We need to upload the zip file into the above folder and run the given code.
Now I can see that I can access my container and download the zip file located inside the container.

ZipArchive creates invalid zip file in list from webservices

I have a problem with get files to zip.
The web service is giving me the right files, for example www.XYP.com/GetFile?=1234 , when I open the Url, automaticly downloads the file, but after I zip this document its not correct files, which are destroyes
My code is here:
private void CreatedZipFile(Dictionary<int, string> listChecked)
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (ZipArchive archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
{
foreach (KeyValuePair<int, string> kvp in listChecked)
{
ZipArchiveEntry demoFile = archive.CreateEntry(kvp.Key.ToString() + kvp.Value.ToString() + ".pdf");
string strDownLoad = System.Configuration.ConfigurationManager.AppSettings["GETFILESERVICES"] + kvp.Key.ToString();
WebService control = new WebService();
var clientnew = new System.Net.WebClient().DownloadData(strDownLoad);
using (var entryStream = demoFile.Open())
{
using (StreamWriter streamWriter = new StreamWriter(entryStream))
{
streamWriter.BaseStream.Write(clientnew, 0, clientnew.Length);
streamWriter.Close();
}
}
}
}
byte[] bytesInStream = memoryStream.ToArray();
Response.ContentType = "application/zip";
Response.AddHeader("content-disposition", "attachment; filename=file.zip");
Response.Buffer = true;
Response.Clear();
Response.BinaryWrite(bytesInStream);
Response.Flush();
//MemoryStream.WriteTo(Response.OutputStream); //works too
Response.End();
}
}
Thanks for help or any advice,

Open a pdf file(using bytes) stored in Azure Blob storage

I am trying to tweak the old logic to support files from blob, Can anyone guide me how to open a pdf file which is stored in azure blob storage.
I tried to search and found the answer How to download a file to browser from Azure Blob Storage
which is using SAS configuration to do that (if i am not wrong).
Is there any way to do by converting to bytes?
Earlier logic to open a pdf file from windows location
Response.Buffer = true;
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
Response.ContentType = "application/pdf";
Response.AppendHeader("content-disposition", "inline; filename=" + mapid + ".pdf");
FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
BinaryReader br = new BinaryReader(fs);
Byte[] dataBytes = br.ReadBytes((int)(fs.Length - 1));
Response.BinaryWrite(dataBytes);
br.Close();
fs.Close();
I am rewritting the logic to read the file from blob, below code is what i have tried so far,
Byte[] dataBytes1;
CloudBlockBlob blobfile = GetStorageAccount(true).GetBlockBlobReference(filename);
blobfile.FetchAttributes();
using (StreamReader blobfilestream = new StreamReader(blobfile.OpenRead()))
{
dataBytes1 = blobfilestream.CurrentEncoding.GetBytes(blobfilestream.ReadToEnd());
}
Byte[] value = BitConverter.GetBytes(dataBytes1.Length - 1);
Response.BinaryWrite(value);
But the file is not opening with error "Failed to Load".
Can anyone guide me if this is good approach to do it?
You could use DownloadToStreamAsync and use the Response.OutputStream as the destination stream.
await blob.DownloadToStreamAsync(Response.OutputStream);
You can use DownloadToByteArray, sample code(in asp.net mvc project) as below, and works fine at my side:
public ActionResult DownloadFile()
{
CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials("your_account", "your_key"), true);
CloudBlobClient client = storageAccount.CreateCloudBlobClient();
CloudBlobContainer blobContainer = client.GetContainerReference("t11");
CloudBlockBlob blob = blobContainer.GetBlockBlobReference("ss22.pdf");
blob.FetchAttributes();
long fileByteLength = blob.Properties.Length;
byte[] fileContent = new byte[fileByteLength];
for (int i=0;i<fileByteLength;i++)
{
fileContent[i] = 0x20;
}
blob.DownloadToByteArray(fileContent,0);
Response.BinaryWrite(fileContent);
return new EmptyResult();
}
Or as per #hardkoded mentioned, you can either use DownloadToStreamAsync or DownloadToStream per your need.
Sample code as below(asp.net mvc project):
public ActionResult DownloadFile()
{
CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials("your_account", "your_key"),true);
CloudBlobClient client = storageAccount.CreateCloudBlobClient();
CloudBlobContainer blobContainer = client.GetContainerReference("t11");
CloudBlockBlob blob = blobContainer.GetBlockBlobReference("ss22.pdf");
blob.DownloadToStream(Response.OutputStream);
return new EmptyResult();
}
The test result as below:
As hardkoded mentioned above, you need to use DownloadToStreamAsync. Below is my code.
blobfile.FetchAttributes();
using (StreamReader blobfilestream = new StreamReader(blobfile.OpenRead()))
{
dataBytes1 = blobfilestream.CurrentEncoding.GetBytes(blobfilestream.ReadToEnd());
await blobfile.DownloadToStreamAsync(Response.OutputStream);
}
Byte[] value = BitConverter.GetBytes(dataBytes1.Length - 1);
string mimeType = "application/pdf";
Response.AppendHeader("Content-Disposition", "inline; filename="+ filename);
return File(value, mimeType);
public async System.Threading.Tasks.Task<ActionResult> DownloadFile()
{
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
ConfigurationManager.ConnectionStrings["azureconnectionstring"].ConnectionString);
CloudBlobClient client = storageAccount.CreateCloudBlobClient();
CloudBlobContainer blobContainer = client.GetContainerReference("my-blob-storage");
CloudBlockBlob blob = blobContainer.GetBlockBlobReference("filename.pdf");
var exists = blob.Exists(); // to verify if file exist
blob.FetchAttributes();
byte[] dataBytes1;
using (StreamReader blobfilestream = new StreamReader(blob.OpenRead()))
{
dataBytes1 = blobfilestream.CurrentEncoding.GetBytes(blobfilestream.ReadToEnd());
await blob.DownloadToStreamAsync(Response.OutputStream);
}
Byte[] value = BitConverter.GetBytes(dataBytes1.Length - 1);
string mimeType = "application/pdf";
Response.AppendHeader("Content-Disposition", "inline; filename=" + "filename.pdf");
return File(value, mimeType);
}

Can't open pdf in new Chrome browser tab

I can't figure out how to open a pdf in a new Chrome tab. The following code works on Internet Explorer but not for Chrome. I checked the setting in Chrome and it is set to the following:
My view:
#Html.ActionLink("View", "OpenFileEncrypted", "Storage", new { fileNumber = item.accession_number, fileType = 2, openType = "NewTab" }, new { #class = "btn btn-primary ViewDownloadButton", #runat="server", #target = "_blank", #onclick = "javascript:clickView(" + item.accession_number + ")" })
The javascript function ClickView checks a checkbox on the web
page.
My Controller:
public ActionResult OpenFileEncrypted(int? fileNumber, int? fileType, string openType)
{
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
CloudConfigurationManager.GetSetting("StorageConnectionString"));
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = GetContainer(blobClient, Convert.ToInt32(fileType));
KeyVaultKeyResolver cloudResolver = new KeyVaultKeyResolver(GetToken);
var fileName = Convert.ToString(fileNumber) + ".pdf";
CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName);
BlobEncryptionPolicy policy = new BlobEncryptionPolicy(null, cloudResolver);
BlobRequestOptions options = new BlobRequestOptions() { EncryptionPolicy = policy };
var memStream = new MemoryStream();
blockBlob.DownloadToStream(memStream, null, options, null);
if (openType == null)
{
openType = "NewTab";
}
order_info OInfo = Ldb.order_info.Where(o => o.accession_number == fileNumber).FirstOrDefault();
switch (openType)
{
case "NewTab":
Response.AddHeader("Content-Disposition", "Inline; filename=" + fileName);
OInfo.ReportViewed = true;
break;
case "Download":
Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
OInfo.ReportDownloaded = true;
break;
}
if (OInfo != null)
{
Ldb.Entry(OInfo).State = EntityState.Modified;
Ldb.SaveChanges();
}
return File(memStream.ToArray(), blockBlob.Properties.ContentType);
It works in IE but not Chrome. When the button is clicked it opens a new tab then opens a download box to name and select the folder where the .pdf is downloaded.
What am I doing wrong?
I had to update the update the ContentType to "application/pdf"
return File(memStream.ToArray(), "application/pdf");
The ContentType was "application/octet-stream"

C# No Data in Folder after Downloading ASP

Let me start off by saying I'm sure this is something that's quite simple, unfortunately I just can't seem to figure it out. So here's my problem, I query the database, return what I need, zip it all up, and prompt user to save. When You attempt to open this, there are no files inside the folder. Where has my data gone? I stepped through everything, and it appears to write everything properly. Any help would be greatly appreciated!!
if (e.CommandName == "DownloadAttachment")
{
e.Canceled = true;
// Create a zip and send it to the client.
//Response.Write(#"<script language='javascript'>alert('Details saved successfully')</script>");
var item = e.Item as GridEditableItem;
fileId = (int)item.GetDataKeyValue("Unique");
FileData[] allrecords = null;
using (
SqlConnection conn =
new SqlConnection(ConfigurationManager.ConnectionStrings["PtcDbModelEntities"].ConnectionString))
{
using (
SqlCommand comm = new SqlCommand("Select Unique1, BinaryData, FileName from PtcDbTracker.dbo.CafFileTable where Unique1=#fileId AND FileName IS NOT NULL", conn))
{
comm.Parameters.Add(new SqlParameter("#fileId", fileId));
conn.Open();
using (var reader = comm.ExecuteReader())
{
var list = new List<FileData>();
while (reader.Read())
{
list.Add(new FileData { Unique1 = reader.GetInt32(0) });
long len = reader.GetBytes(1, 0, null, 0, 0);
Byte[] buffer = new byte[len];
list.Add(new FileData { BinaryData = (byte)reader.GetBytes(1, 0, buffer, 0, (int)len), FileName = reader.GetString(2) });
allrecords = list.ToArray();
}
}
conn.Close();
}
}
using (var compressedFileStream = new MemoryStream())
{
//Create an archive and store the stream in memory.
using (var zipArchive = new ZipArchive(compressedFileStream, ZipArchiveMode.Update, false))
{
if (allrecords != null)
{
foreach (var record in allrecords)
{
//Create a zip entry for each attachment
if (record.FileName != null)
{
var zipEntry = zipArchive.CreateEntry(record.FileName);
//Get the stream of the attachment
using (var originalFileStream = new MemoryStream(record.BinaryData))
{
using (var zipEntryStream = zipEntry.Open())
{
//Copy the attachment stream to the zip entry stream
originalFileStream.CopyTo(zipEntryStream);
}
}
}
}
}
Response.ClearContent();
Response.ClearHeaders();
Response.BinaryWrite(compressedFileStream.ToArray());
Response.AppendHeader("Content-Disposition", "Attachment; filename=result.zip");
Response.Flush();
Response.Close();
zipArchive.Dispose();
//How Do I Prompt for open or save?
}
}
Are you sure the BinaryWrite is getting a valid ByteArray?
In any case here's a tested method to output a file to the Response with the typically needed headers for binary attachments:
public bool WriteFile(byte[] byteContent, DateTime dtTimeStamp, string urlFilename)
{
HttpContext context = HttpContext.Current;
HttpResponse response = context.Response;
response.Clear();
response.ClearHeaders();
response.ClearContent();
response.BufferOutput = true;
response.AppendHeader("Content-Length", byteContent.Length.ToString());
response.AppendHeader("Content-Type", "application/octet-stream");
response.AppendHeader("Last-Modified", dtTimeStamp.ToString("R"));//Last-Modified Wed, 28 Aug 2013 10:16:46 GMT
response.AppendHeader("Content-Disposition", "inline; filename=\"" + urlFilename + "\"");
response.BinaryWrite(byteContent);
response.Flush();
// Prevents any other content from being sent to the browser
response.SuppressContent = true;
context.ApplicationInstance.CompleteRequest();
return true;
}

Categories

Resources