Uploading .mp4 to Azure Media Service from web api C# - c#

I have an API written in C# that is meant to recieve a file from frontend. As of now it's a byte array and i want to convert this to a .mp4 file and then send it to my azure media service with the blobstorage. I do not want to store it locally and i can't read it from disk either. What is the best approach for this?
I create my CloudBlobClient like so:
private CloudBlobClient CloudBlobClient()
{
var storageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["StorageConnection"].ConnectionString);
var blobStorage = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobStorage.GetContainerReference(Constants.VideoBlobContainer);
if (container.CreateIfNotExist())
{
var permissions = container.GetPermissions();
permissions.PublicAccess = BlobContainerPublicAccessType.Container;
container.SetPermissions(permissions);
}
return blobStorage;
}
Then I have this method that i've started
private Uri UploadToStorage(CloudBlobClient blobStorage, byte[] video, VideoSize size)
{
var uniqueBlobName = GetVideoUriAsString(VideoId, Type, size);
CloudBlockBlob blob = blobStorage.GetBlockBlobReference(uniqueBlobName);
I'm not sure how to proceede here. I have been looking around a lot on the web for approaches but all I find is example of console applications reading from disk.
Is there anyone familliar with this type of uploading to media serivces?

You're on your way there, although you should just obtain the reference to the blob from the blob container from the first method. Very rough but here you go:
public void uploadBytesToBlobWithMimeAndStorageCreds(string theFolder, string theFileName, byte[] videoBytes, string theMimeType)
{
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["StorageConnection"].ConnectionString);
CloudBlobClient client = storageAccount.CreateCloudBlobClient;
CloudBlobContainer container = client.GetContainerReference(theFolder);
CloudBlob blob = container.GetBlobReference(theFileName);
blob.UploadByteArray(theBytes);
blob.Properties.CacheControl = "max-age=3600, must-revalidate";
blob.Properties.ContentType = theMimeType; // e.g. "video/mp4"
blob.SetProperties();
}

Related

trying to download the word document from azure blob

i am trying to download the word document stored in azure blob container having private access and i need to convert downloaded document into byte array so that i can be able to send to react app
this is the code i am trying below
[Authorize, HttpGet("{id}/{projectphase?}")]
public async Task<ActionResult<DesignProject>> GetDesignProject(string id, string projectphase = null)
{
var blobContainerName = Startup.Configuration["AzureStorage:BlobContainerName"];
var azureStorageConnectionString = Startup.Configuration["AzureStorage:ConnectionString"];
BlobContainerClient blobContainerClient = new BlobContainerClient(azureStorageConnectionString, blobContainerName);
blobContainerClient.CreateIfNotExists();
....... // not sure how to proceed further
.......
......
return new InlineFileContentResult('here i need to return byte array???', "application/docx") { FileDownloadName = fileName };
}
I have got the full path name where the file has been stored like as below
https://xxxx.blob.core.windows.net/design-project-files/99999-99/99999-99-BOD-Concept.docx
and then i have got the file name as well 99999-99-BOD-Concept.docx
Could any one please guide me how to proceed with the next to download the document that would be very grateful to me.
Please try something like the following (untested code though):
public async Task<ActionResult<DesignProject>> GetDesignProject(string id, string projectphase = null)
{
var blobContainerName = Startup.Configuration["AzureStorage:BlobContainerName"];
var azureStorageConnectionString = Startup.Configuration["AzureStorage:ConnectionString"];
BlobContainerClient blobContainerClient = new BlobContainerClient(azureStorageConnectionString, blobContainerName);
blobContainerClient.CreateIfNotExists();
var blobClient = new BlobClient("https://xxxx.blob.core.windows.net/design-project-files/99999-99/99999-99-BOD-Concept.docx");
var blobName = blobClient.Name;
blobClient = new BlobClient(azureStorageConnectionString, blobContainerName, blobName);
using (var ms = new MemoryStream())
{
await blobClient.DownloadToAsync(ms);
return new InlineFileContentResult(ms.ToArray(), "application/docx") { FileDownloadName = fileName };
}
}
Basically what we're doing is that we're first creating a BlobClient using the URL that you have so that we can extract blob's name out of that URL (you can do URL parsing as well). Once we have the blob's name, we create a new instance of BlobClient using connection string, blob container name and blob's name.
Then we download the blob's content as stream and convert that stream to byte array (this part I am not 100% sure that my code would work) and return that byte array.
You don't really need to have this process where your react app requests to your server, so your server downloads the file and then sends it to the react app; that file in blob storage is on the web, downloadable from blob storage so it's kinda unnecessary to hassle your sevrer into being a proxy for it
If you configure public access for blobs then you just put that URL into your react app - user clicks it, bytes download. Happy days. If you have a private container you can still generate SAS URLs for the blobs
If you actually need the bytes in your react app, then just fetch it with a javascript web request - you'll need to set a CORS policy on the blob container though
If you really want to download the file to/via the server, you'll probably have to get into streaming it to the response stream connected to the react app, passed into the SOMETHING below:
BlobClient blob = blobContainerClient.GetBlobClient( BLOB NAME I.E PATH INSIDE CONTAINER);
//download to a file or stream
await blob.DownloadToAsync( SOMETHING );

How can I get a BLOB and add it to my configuration?

I have a web api that uses a bunch of appSettings files to load test data.
I want to shift the location of that data to an Azure Blob.
Based on the test infrastructure, I'd like to convert the Blob into an IConfiguration object.
To accomplish this, I wanted to use the AddJsonStream onto a ConfigurationBuilder.
I created this method to go out and grab the blob and convert it to a stream:
public static Stream GetBlobAsStream(Uri blobURI)
{
var storageAccount = CloudStorageAccount.Parse(AZURE_STORAGE_CONNECTION_STRING);
var cloudBlobClient = storageAccount.CreateCloudBlobClient();
var cloudBlobContainer = cloudBlobClient.GetContainerReference(blobContainer);
var cloudBlob = cloudBlobContainer.GetBlockBlobReference(blobName);
var stream = cloudBlob.OpenRead();
return stream;
}
Now this method uses a bunch of hard coded constants - which I'd like to remove.
How can I remove the hard coding, and find the needed azure info based on the Environment in which it's being run?
Or have I programmed myself into a corner here?
You could try to create an instance of CloudBlockBlob using the Blob URI and Blob Client by doing something like:
public static Stream GetBlobAsStream(Uri blobURI)
{
var storageAccount = CloudStorageAccount.Parse(AZURE_STORAGE_CONNECTION_STRING);
var cloudBlobClient = storageAccount.CreateCloudBlobClient();
var cloudBlob = new CloudBlockBlob(blobURI, cloudBlobClient);
var stream = cloudBlob.OpenRead();
return stream;
}
or create an instance of CloudBlockBlob using the Blob URI and Storage Credentials by doing something like:
public static Stream GetBlobAsStream(Uri blobURI)
{
var storageAccount = CloudStorageAccount.Parse(AZURE_STORAGE_CONNECTION_STRING);
var cloudBlob = new CloudBlockBlob(blobURI, storageAccount.Credentials);
var stream = cloudBlob.OpenRead();
return stream;
}

Unable to download Block Blob with DownloadToFileAsync method C#

I am trying to download a block blob from Azure using C#. The code I am using is below.
In other tests, I am able to list the blobs in the container but I am unable to download a specific blob. It doesn't give me an exception or error but the file when created locally is empty.
I have cleared out the connection string for obvious reasons.
Does my code look ok?
var containerName = "samples-workitems";
CloudStorageAccount storageAccount = CloudStorageAccount.Parse("DefaultEndpointsProtocol=xxxxxxxxxxxxxxxxxx.windows.net");
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference(containerName);
try {
CloudBlockBlob blockBlob = container.GetBlockBlobReference("file.png");
var localPath = string.Format("C:\\users\\user\\downloads\\file.png");
blockBlob.DownloadToFileAsync(localPath, FileMode.Create);
catch
{
}
You know what - I have been stuck on this since yesterday and since posting this 2 minutes ago - I removed...
CloudBlockBlob blockBlob = container.GetBlockBlobReference("file.png");
var localPath = string.Format("C:\\users\\user\\downloads\\file.png");
these 2 lines of code from within the try statement and put them above it. It now works?!
Why is that?

Azure blob storage returns 404 with some files

I have an Azure blob storage setup with a couple of files in it. I am able to download the files into a Stream when they are small (KB sized), but when the files are a little larger (MB sized) I get a 404 error. I have manually downloaded from the portal one of the images that is returning 404 fine and have resized that image and then uploaded the smaller image back to the container and I can then grammatically download it into a stream.
Here is the code that I'm using to download the blob
private static byte[] PerformDownload(string fileName, CloudBlobContainer container)
{
var blockBlob = container.GetBlockBlobReference(fileName);
using (var memoryStream = new MemoryStream())
{
blockBlob.DownloadToStream(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
var binaryReader = new BinaryReader(memoryStream);
var bytes = binaryReader.ReadBytes((int)memoryStream.Length);
return bytes;
}
}
The container is passed into this method and as I mentioned I can download some files from the container without issue, but if you need that code I can add that as well
The container is retrieve using the standard examples that you find, but here is the code
private static CloudBlobContainer GetContainer(string containerName)
{
var storageAccount = CloudStorageAccount.Parse(ConnectionString);
var container = CreateContainerIfNeeded(storageAccount, containerName);
return container;
}
private static CloudBlobContainer CreateContainerIfNeeded(CloudStorageAccount storageAccount, string containerName)
{
var blobClient = storageAccount.CreateCloudBlobClient();
var container = blobClient.GetContainerReference(containerName);
container.CreateIfNotExists();
return container;
}
Also Case sensitivity is not the issue because the container's name is 2017-106 and the file is 4448.jpg.
I am able to download the files into a Stream when they are small (KB sized), but when the files are a little larger (MB sized) I get a 404 error.
Currently max size of a block blob is approx. 4.75 TB, storing MB-sized data in a block blob, which should not cause Azure Blob service return 404 when you access the blob. 404 error indicates that the specified blob does not exist, as Gaurav Mantri said, Blob name is case-sensitive, please make sure the filename (blob name) you provided indeed exists in your container.
Besides, If only that specific blob can not be found, but it is really existing in your container, you can create support request to report it.

Upload file to Azure Blob from HTML webpage (C#)?

I am trying to figure out how to take a file from an html form and save it to my Azure Blob storage. I have found many posts about doing this for JavaScript but I am trying to do it via C#. One source I found said to do
using (YourFileUpload.PostedFile.InputStream)
{
blockBlob.UploadFromStream((FileStream)YourFileUpload.PostedFile.InputStream);
}
but PostedFile does not exist in the HttpPostedFileBase object.
The code I have built out so far is
public static int UploadFile(string FileName, HttpPostedFileBase UploadedFile, int ExistingFileID = 0)
{
var StorageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["StorageConnectionString"].ToString());
var BlobClient = StorageAccount.CreateCloudBlobClient();
var Container = BlobClient.GetContainerReference("ffinfofiles");
var BlobBlock = Container.GetBlockBlobReference(FileName);
var FileExtension = Path.GetExtension(UploadedFile.FileName.ToLower());
using (UploadedFile.InputStream)
{
BlobBlock.UploadFromStream((FileStream)UploadedFile.InputStream);
}
but when I run this I get the error:
Unable to cast object of type 'System.Web.HttpInputStream' to type 'System.IO.FileStream'.
What method do I need to do so I can upload the file to the Azure Blob?
You should not try to cast UploadedFile.InputStream to a FileStream. CloudBlockBlob.UploadFromStream requires a Stream object, so it should be able to work directly with UploadedFile.InputStream.

Categories