File upload to Azure Blob storage

Is there an example of uploading a file to Azure Blob storage?

We don’t have such example. Just a note: upload binary data to a database field usually is a two step process. First you need to upload the file and later save the file to desired database record.

Is there an example of uploading a file?

I am starting off with

Is there any examples/documentation in addition to that?

Yes, these are the Upload component examples - all of them are uploading files. The component will post binary file(s) data to a url and for our demos this is handled in the UploadController:

There isn't anything else.

Ok, thank you.

Have any community members done this? Would appreciate any knowledge share!

I see how the file is being captured (see below), I'll have to figure out what to do with it.

Will start with this

Got the file upload to Azure Blob storage working along with a database record with pertinent file information.

My use case it being able to upload files and link them to an entity.

db table

image

Razor page

        <RadzenUpload Url="upload/single" Complete=@OnCompleteAsync class="w-100">
        </RadzenUpload>

Code Behind (this runs AFTER file is uploaded which happens in the UploadController. It fires based on Complete=@OnCompleteAsync in the RadzenUpload control, it's native to the control)

    async Task OnCompleteAsync(UploadCompleteEventArgs args)
    {
        var guid = args.RawResponse.Substring(0, 36);
        var fileName = args.RawResponse.Remove(0, 36);

        var customerFile = new CustomerFile
        {
            Id = guid,
            CustomerId = CustomerId,
            FileName = fileName
        };

        await sql_databaseService.CreateCustomerFile(customerFile);
        DialogService.Close(customerFile);
    }

Azure piece:

--create Storage account resource
--create container in the Storage account resource
--get connection string as shown below
--install "Azure.Storage.Blobs" Nuget

Upload Controller

    private static string connectionString = "DefaultEndpointsProtocol=xxxxxxxxxxxxxxxxxxxxx";
    private static string containerName = "all-files";

    // Single file upload
    [HttpPost("upload/single")]
    public IActionResult Single(IFormFile file)
    {
        try
        {
            BlobServiceClient blobServiceClient = new BlobServiceClient(connectionString);

            var container = new BlobContainerClient(connectionString, "all-files");

            var guid = Guid.NewGuid();

            using (var stream = file.OpenReadStream())
            {
                container.UploadBlob(guid.ToString() + "-" + file.FileName, stream);
            }

            return StatusCode(200, guid + file.FileName);
        }
        catch (Exception ex)
        {
            return StatusCode(500, ex.Message);
        }
    }

Happy to answer any questions of anyone happens to come across this.

Now to figure out the download...

1 Like

Hi @Chad are you able to share a simple project so I can see how this works ?

1 Like

Did you have specific questions about code I posted above?

Hi,

I don't fully understand the code, which bit happens first etc. I wanted a cut-down version without the database update. Using VisualStudio, I installed the NuGet Package for Azure.Storage.Blobs .I updated the standard public IActionResult Single(IFormFile file) in the UploadController.cs with the following;

[HttpPost("upload/single")]
        public IActionResult Single(IFormFile file)
        {
            try
            {
                BlobServiceClient blobServiceClient = new BlobServiceClient(connectionString);

                var container = new BlobContainerClient(connectionString, "all-files");

                var guid = Guid.NewGuid();

                using (var stream = file.OpenReadStream())
                {
                    container.UploadBlob(guid.ToString() + "-" + file.FileName, stream);
                }

                return StatusCode(200, guid + file.FileName);
            }
            catch (Exception ex)
            {
                return StatusCode(500, ex.Message);
            }
        }

Within my page Template.razor.cs I added the following

        async Task OnCompleteAsync(UploadCompleteEventArgs args)
        {
            var guid = args.RawResponse.Substring(0, 36);
            var fileName = args.RawResponse.Remove(0, 36);           
        }

But I'm unsure how to trigger the upload using the upload from the toolbox.

image

image

do you have your Azure storage container set up?

have you reviewed this?

I'm not sure how to add it from the toolbox, I mostly just look at examples and put code in manually.

The OnCompleteAsync is OPTIONAL, it's not needed at all to do the upload itself, I have it to store info into my database.

the simplest is to just add this to your form

            <RadzenUpload Url="upload/single" class="w-100">
            </RadzenUpload>

and then set a breakpoint on your Method in the upload controller.

when you select the file and it hits the breakpoint, you have the file object, then the rest of the code does the upload.

hope this helps, let's keep working on it until you get it working, happy to help

all the events you are looking at in the picture you posted are optional.

Hi Chad,

Thanks for the run-through, I have managed to assign the URL via the Radzen UI.

But more importantly, I have managed to complete an upload, within the setup I had left the "all-files" in the container name.

var container = new BlobContainerClient(connectionString, "all-files");

Which was causing the upload to fail, I updated this to pull it from above

private static string containerName = "my container name";

        // Single file upload
        [HttpPost("upload/single")]
        public IActionResult Single(IFormFile file)
        {
            try
            {
                BlobServiceClient blobServiceClient = new BlobServiceClient(connectionString);

                var container = new BlobContainerClient(connectionString, containerName);

Uploads are working as expected now, just on to the downloads.

Thank you for your help, and original post so I can copy and paste :slight_smile:

1 Like

glad you got it working.

for downloads, the way I did it was, you need this in your Razor page you want to download from (assuming you have "BlobBaseURL" in your appsettings.json file, could just hard code it if you want and skip this)

@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
@{
    var blobBaseURL = Configuration.GetSection("Azure")["BlobBaseURL"];
}

then I did this, but I'm pulling ID and name out of the database which I stored when I uploaded the file, I recall you didn't want/need to do this, so not sure what you have in mind at this point, can just hard code everything? I don't know your application design...

<RadzenDataGridColumn TItem="RadzenBlazorServerApp.Models.sql_database.LocationFile" Property="FileName" Title="File Name">
    <Template Context="locationFileChild">
        <RadzenLink Path="@(blobBaseURL + locationFileChild.Id + "-" + locationFileChild.FileName)" Text="@locationFileChild.FileName" />
    </Template>
</RadzenDataGridColumn>

The filename is already in the database, which is completed by a 3rd party workflow. I may insert it with the upload if required later. In order for your code to function, would the access level on the blob need to be public?

image

yes.

I just checked, that is what I have currently, will have to think about what I want to do long term, glad this came up...