I have zipped a file and upload to a blob in azure , but I am unable to download it after unzipping it. I have tried the below code but it is throwing error:
public FileStream Download(string strPath)
{
Stream fs = GetFile(strPath);
using (ZipArchive zip = new ZipArchive(fs))
{
var entry = zip.Entries.First();
var memoryStream = entry.Open();
string filename = "Report_" + GetUploadTime();
using (var fileStream = new FileStream(filename,
FileMode.CreateNew,
FileAccess.ReadWrite))
{
memoryStream.CopyTo(fileStream); // fileStream is not populated
return fileStream;
}
}
}
System.UnauthorizedAccessException occurred in mscorlib.dll but was not handled in user code, I do not want to create any folder or keep it anywhere just unzip and download how to do it.
public Stream GetFile(string strPath)
{
try
{
var filename = Path.GetFileName(strPath);
string account = ConfigurationManager.AppSettings["BlobContainer"];
string key = ConfigurationManager.AppSettings["BlobKey"];
string connectionString =
string.Format("DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}",
account, key);
CloudStorageAccount storageAccount =
CloudStorageAccount.Parse(connectionString);
var blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("reportportalblob");
CloudBlockBlob blob = container.GetBlockBlobReference(filename);
Stream blobStream = blob.OpenRead();
return blobStream;
}
catch (Exception)
{
// download failed
// handle exception
throw;
}
}
I have search for some code but I am not getting anything, please help.
We could get the unzip stream with following code.
public MemoryStream GetFile(string strPath)
{
try
{
var filename = Path.GetFileName(strPath);
string account = ConfigurationManager.AppSettings["accountName"];
string key = ConfigurationManager.AppSettings["accountKey"];
string containerName = "test";
string connectionString =$"DefaultEndpointsProtocol=https;AccountName={account};AccountKey={key}";
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);
var blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference(containerName);
CloudBlockBlob blob = container.GetBlockBlobReference(filename);
MemoryStream memory = new MemoryStream();
blob.DownloadToStream(memory);
var zipArchive = new ZipArchive(memory, ZipArchiveMode.Read, true);
var entry = zipArchive.Entries.First();
if (entry != null)
{
var stream = entry.Open();
memory = new MemoryStream();
stream.CopyTo(memory);
memory.Position = 0;
return memory;
}
return null;
}
catch (Exception)
{
// download failed
// handle exception
throw;
}
}
If we want to down to file, then we could use File.WriteAllBytes(strPath,memory.ToArray()); or fileStream.Write(memory.ToArray(),0,memory.ToArray().Length-1);
public void Download(string strPath)
{
var memory = GetFile(strPath);
string filename = "Report_" + DateTime.Now;
var fileStream = new FileStream(filename,
FileMode.CreateNew,
FileAccess.ReadWrite);
// File.WriteAllBytes(strPath,memory.ToArray());
fileStream.Write(memory.ToArray(),0,memory.ToArray().Length-1);
}
Related
I am trying to update a JSON file which is located in azure blob storage. when the program does the put call the saved file looks like this:
Zona de especial protecci\u00F3n
the accents and other characters are the matter, but that only happens when I download the file from the azure UI interface if I do a get from postman, that does not happen. this is my code:
SemanticDictionaryContent semanticDictionaryContent = new SemanticDictionaryContent()
{
Name = entity.Id + JSON_EXTENSION,
Content = BinaryData.FromObjectAsJson(entity)
};
Create a storage account in azure.
Create a container in azure.
Uploaded a Json file to a container using the below code.
I have used the below approach in Uploading / downloading / editing the Json file.
public static bool Upload()
{
try
{
var containerName = "mycontainer";
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConnectionSting);
CloudBlobClient client = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = client.GetContainerReference(containerName);
var isCreated = container.CreateIfNotExists();
container.SetPermissionsAsync(new BlobContainerPermissions { PublicAccess = BlobContainerPublicAccessType.Blob });
using (FileStream fileStream = File.Open(#"C:\Tools\local.settings.json", FileMode.Open))
{
using (MemoryStream memoryStream = new MemoryStream())
{
memoryStream.Position = 0;
fileStream.CopyTo(memoryStream);
var fileName = "local.settings.json";
CloudBlockBlob blob = container.GetBlockBlobReference(fileName);
string mimeType = "application/unknown";
string ext = (fileName.Contains(".")) ? System.IO.Path.GetExtension(fileName).ToLower() : "." + fileName;
Microsoft.Win32.RegistryKey regKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext);
if (regKey != null && regKey.GetValue("Content Type") != null) mimeType = regKey.GetValue("Content Type").ToString();
memoryStream.ToArray();
memoryStream.Seek(0, SeekOrigin.Begin);
blob.Properties.ContentType = mimeType;
blob.UploadFromStream(memoryStream);
}
}
return true;
}
catch (Exception ex)
{
throw;
}
}
Uploaded Json file
Updated the Json file in azure and uploaded it using the below code.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConnectionSting);
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("mycontainer");
CloudBlockBlob jsonBlob = container.GetBlockBlobReference("local.settings.json");
string jsonText = jsonBlob.DownloadText();
dynamic jsonData = JsonConvert.DeserializeObject(jsonText);
jsonData.property1 = "Property1";
jsonData.property2 = "Property2";
jsonBlob.UploadText(JsonConvert.SerializeObject(jsonData));
And downloaded the Json file from azure manually and do not find any special characters.
Context: Encrypt and Decrypt an audio file (.wav) in Azure Storage.
Issue: inputStream must be seek-able (when encrypting) "await pgp.EncryptStreamAsync(sourceStream, outputStream);"
I'm not a C# Developer :)
Thank you for your help,
Here is the code i'm using:
static async Task Main()
{
string connectionString = Environment.GetEnvironmentVariable("AZURE_STORAGE_CONNECTION_STRING");
////Create a unique name for the container
string containerName = "audioinput";
string filename = "abc.wav";
//// Create a BlobServiceClient object which will be used to create a container client
BlobServiceClient blobServiceClient = new BlobServiceClient(connectionString);
BlobContainerClient sourcecontainer = blobServiceClient.GetBlobContainerClient(containerName);
BlobClient blobClient = sourcecontainer.GetBlobClient(filename);
if (sourcecontainer.Exists())
{
var sourceStream = new MemoryStream();
//Download blob to MemoryStream
await blobClient.DownloadToAsync(sourceStream);
sourceStream.Position = 0;
//OutputStream
await using var outputStream = new MemoryStream();
//Get encryptionkeys
EncryptionKeys encryptionKeys;
using (Stream publicKeyStream = new FileStream(#"...\public.asc", FileMode.Open))
encryptionKeys = new EncryptionKeys(publicKeyStream);
PGP pgp = new PGP(encryptionKeys);
await pgp.EncryptStreamAsync(sourceStream, outputStream);
}
else
{
Console.WriteLine("container doesn't exist");
}
}
Below is the method where I am reading a csv file from an azure blob container and later calling a function to copy the contents in a tabular storage.
Now my requirement has bit changed and now .csv file will be compressed to .gz file in the blob container. I would like to know, how can I modify the below code so that I can read .gz file , decompress it and then pass the contents as I am already passing
public async Task<string> ReadStream(string BlobcontainerName, string fileName, string connectionString)
{
var contents = await DownloadBlob(BlobcontainerName, fileName, connectionString);
string data = Encoding.UTF8.GetString(contents.ToArray());
return data;
}
foreach (var files in recFiles)// recFiles are list of CSV files
{
string data = await ReadStream(containerName, files.Name, connectionString);}
public async Task<MemoryStream> DownloadBlob(string containerName, string fileName, string connectionString)
{
MemoryStream memoryStream = new MemoryStream();
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);
CloudBlobClient serviceClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = serviceClient.GetContainerReference(containerName);
CloudBlockBlob blob = container.GetBlockBlobReference(fileName);
if (blob.Exists())
{
using (memoryStream = new MemoryStream())
{
await blob.DownloadToStreamAsync(memoryStream);
}
}
return memoryStream;
}
Try this code:
public async Task<MemoryStream> DownloadBlob(string containerName, string fileName, string connectionString)
{
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);
CloudBlobClient serviceClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = serviceClient.GetContainerReference(containerName);
CloudBlockBlob blob = container.GetBlockBlobReference(fileName);
var memoryStream = new MemoryStream();
if (blob.Exists())
{
using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Decompress))
{
await blob.DownloadToStreamAsync(gZipStream);
}
}
return memoryStream;
}
I have 2 methods to upload files to Blob Storage. 'UploadFileToContainer' is working fine, and i get files with data in container. The problem is 'UploadOrReplaceFileToContainer', where it's not possible to use file.Position = 0, returning the follow error:
System.NotSupportedException: 'Specified method is not supported.'
Can someone help?
public void UploadFileToContainer(Stream file, string fileName, string userId)
{
string uniqueFileName = GetFileNameUniqueId(fileName);
BlobClient blob = _container.GetBlobClient(fileName);
blob.Upload(file);
file.Position = 0;
BlobClient blob2 = _containerbackup.GetBlobClient(uniqueFileName);
blob2.Upload(file);
_log.LogFileUpload(fileName, uniqueFileName, userId, DateTime.Now);
}
public int UploadOrReplaceFileToContainer(Stream file, string fileName, string userId)
{
string uniqueFileName = GetFileNameUniqueId(fileName);
if (_container.GetBlobs().Any(b => b.Name == fileName))
{
_container.DeleteBlob(fileName);
}
BlobClient blob = _container.GetBlobClient(fileName);
blob.Upload(file);
file.Position = 0; //here is where i get the error
BlobClient blob2 = _containerbackup.GetBlobClient(uniqueFileName);
blob2.Upload(file);
int fileUploadId = _log.LogFileUpload(fileName, uniqueFileName, userId, DateTime.Now);
return fileUploadId;
}
You are getting this error suppose your stream type canseek type is false. You could create a new MemoryStream and copy the stream to the MemoryStream then seek it or just set the position.
System.IO.MemoryStream blobstream = new System.IO.MemoryStream();
inputblob.CopyTo(blobstream);
blobstream.Position = 0;
//blobstream.Seek(0, SeekOrigin.Begin);
blob.Upload(blobstream);
Also you could refer to other discussion about this:read a Stream and reset its position to zero.
How can I to Upload a file with C# ? I need to upload a file from a dialogWindow.
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Blob;
// Retrieve storage account from connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse("StorageKey");
// Create the blob client.
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
// Retrieve reference to a previously created container.
CloudBlobContainer container = blobClient.GetContainerReference("mycontainer");
// Retrieve reference to a blob named "myblob".
CloudBlockBlob blockBlob = container.GetBlockBlobReference("myblob");
// Create or overwrite the "myblob" blob with contents from a local file.
using (var fileStream = System.IO.File.OpenRead(#"path\myfile"))
{
blockBlob.UploadFromStream(fileStream);
}
see here about needed SDK and references
i think it's what you need
Since WindowsAzure.Storage is legacy. With Microsoft.Azure.Storage.* we can use the following code to upload
static async Task CreateBlob()
{
BlobServiceClient blobServiceClient = new BlobServiceClient(storageconnstring);
BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);
BlobClient blobClient = containerClient.GetBlobClient(filename);
using FileStream uploadFileStream = File.OpenRead(filepath);
await blobClient.UploadAsync(uploadFileStream, true);
uploadFileStream.Close();
}
The following code snippet is the simplest form of performing the file uploading.
I have added a few more lines to this code, in order to detect the uploading file type and check the container exeistance.
Note:- you need to add the following NuGet packages first.
Microsoft.AspNetCore.StaticFiles
Microsoft.Azure.Storage.Blob
Microsoft.Extensions.Configuration
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
string connstring = "DefaultEndpointsProtocol=https;AccountName=storageaccountnewne9d7b;AccountKey=3sUU8J5pQQ+6YYIi+b5jo+BiSb5XPt027Rve6N5QP9iPEhMXZAbzUfsuW7QDWi1gSPecsPFpC6AzmA9jwPYs6g==;EndpointSuffix=core.windows.net";
string containername = "newturorial";
string finlename = "TestUpload.docx";
var fileBytes = System.IO.File.ReadAllBytes(#"C:\Users\Namal Wijekoon\Desktop\HardningSprint2LoadTest\" + finlename);
var cloudstorageAccount = CloudStorageAccount.Parse(connstring);
var cloudblobClient = cloudstorageAccount.CreateCloudBlobClient();
var containerObject = cloudblobClient.GetContainerReference(containername);
//check the container existance
if (containerObject.CreateIfNotExistsAsync().Result)
{
containerObject.SetPermissionsAsync(new BlobContainerPermissions { PublicAccess = BlobContainerPublicAccessType.Blob });
}
var fileobject = containerObject.GetBlockBlobReference(finlename);
//check the file type
string file_type;
var provider = new FileExtensionContentTypeProvider();
if(!provider.TryGetContentType(finlename, out file_type))
{
file_type = "application/octet-stream";
}
fileobject.Properties.ContentType = file_type;
fileobject.UploadFromByteArrayAsync(fileBytes, 0 , fileBytes.Length);
string fileuploadURI = fileobject.Uri.AbsoluteUri;
Console.WriteLine("File has be uploaded successfully.");
Console.WriteLine("The URL of the Uploaded file is : - \n" + fileuploadURI);
}
we can use BackgroundUploader class ,Then we need to provide StorageFile object and a Uri:
Required Namespaces:
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Networking.BackgroundTransfer;
using Windows.Storage.Pickers;
using Windows.Storage;
The process is Like This :
Uri is defined using a string value provided via a UI input field, and the desired file for upload, represented by a StorageFile object, is returned when the end-user has selected a file through the UI provided by the PickSingleFileAsync operation
Uri uri = new Uri(serverAddressField.Text.Trim());
FileOpenPicker picker = new FileOpenPicker();
picker.FileTypeFilter.Add("*");
StorageFile file = await picker.PickSingleFileAsync();
and Then:
BackgroundUploader uploader = new BackgroundUploader();
uploader.SetRequestHeader("Filename", file.Name);
UploadOperation upload = uploader.CreateUpload(uri, file);
// Attach progress and completion handlers.
await HandleUploadAsync(upload, true);
Thats All
Here is the complete method.
[HttpPost]
public ActionResult Index(Doctor doct, HttpPostedFileBase photo)
{
try
{
if (photo != null && photo.ContentLength > 0)
{
// extract only the fielname
var fileName = Path.GetFileName(photo.FileName);
doct.Image = fileName.ToString();
CloudStorageAccount cloudStorageAccount = DoctorController.GetConnectionString();
CloudBlobClient cloudBlobClient = cloudStorageAccount.CreateCloudBlobClient();
CloudBlobContainer cloudBlobContainer = cloudBlobClient.GetContainerReference("images");
string imageName = Guid.NewGuid().ToString() + "-" +Path.GetExtension(photo.FileName);
CloudBlockBlob BlockBlob = cloudBlobContainer.GetBlockBlobReference(imageName);
BlockBlob.Properties.ContentType = photo.ContentType;
BlockBlob.UploadFromStreamAsync(photo.InputStream);
string imageFullPath = BlockBlob.Uri.ToString();
var memoryStream = new MemoryStream();
photo.InputStream.CopyTo(memoryStream);
memoryStream.ToArray();
memoryStream.Seek(0, SeekOrigin.Begin);
using (var fs = photo.InputStream)
{
BlockBlob.UploadFromStreamAsync(memoryStream);
}
}
}
catch (Exception ex)
{
}
return View();
}
where the getconnectionstring method is this.
static string accountname = ConfigurationManager.AppSettings["accountName"];
static string key = ConfigurationManager.AppSettings["key"];
public static CloudStorageAccount GetConnectionString()
{
string connectionString = string.Format("DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}", accountname, key);
return CloudStorageAccount.Parse(connectionString);
}
Complete Web API Controller to upload single or multiple files. .NET Framework 4.8
Install NuGet package, Azure.Storage.Blob
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using System;
using System.Configuration;
using System.Web;
using System.Web.Http;
namespace api.azure.Controllers
{
public class FileController : ApiController
{
[HttpPost]
[Route("api/BlobStorage/UploadFiles")]
public IHttpActionResult UploadFiles()
{
string result = "";
try
{
result = UploadFilesToBlob();
}
catch (Exception ex)
{
return Ok(ex.Message);
}
return Ok(result);
}
public string UploadFilesToBlob()
{
try
{
string storageConnectionString = ConfigurationManager.AppSettings["BlobStorageConnectionString"];
CloudStorageAccount blobStorage = CloudStorageAccount.Parse(storageConnectionString);
CloudBlobClient blobClient = blobStorage.CreateCloudBlobClient();
if (HttpContext.Current.Request.Form["BlobContainerName"] != null)
{
string blobContainerName = HttpContext.Current.Request.Form["BlobContainerName"].ToString();
CloudBlobContainer container = blobClient.GetContainerReference(blobContainerName);
container.CreateIfNotExists();
// Set public access level to the container.
container.SetPermissions(new BlobContainerPermissions()
{
PublicAccess = BlobContainerPublicAccessType.Container
});
string folderName = "";
if (HttpContext.Current.Request.Form["FolderNameToUploadFiles"] != null)
folderName = HttpContext.Current.Request.Form["FolderNameToUploadFiles"].ToString() + "/";
for (int i = 0; i < HttpContext.Current.Request.Files.Count; i++)
{
var httpPostedFile = HttpContext.Current.Request.Files[i];
if (httpPostedFile != null)
{
string blobName = folderName + httpPostedFile.FileName;
CloudBlockBlob blob = container.GetBlockBlobReference(blobName);
blob.UploadFromStream(httpPostedFile.InputStream);
}
}
}
}
catch (Exception ex)
{
throw ex;
}
return "# of file(s) sent to upload: " + HttpContext.Current.Request.Files.Count.ToString();
}
}
}