Azure Blob Storage a ASP.NET Core

Nedávno jsem pro jednu geolokační hru vytvářel jednoduchý jednoúčelový jednostránkový (J3, to by se mohlo ujmout…) webík, který dělal jediné: nechal uživatele uploadovat fotky a uložil je do Azure Storage jako Blob. Pojďme se podívat, jak na to.

Web jsem vytvořil v ASP.NET Core 1.0 (neboli bývalém ASP.NET 5) a hostoval ho v Azure.

Dropzone

Aby bylo uploadování pohodlnější, použil jsem knihovnu Dropzone, která pomocí JavaScriptu nahradí standardní formulářové pole hezkým obdélníčkem s podporou drag&drop. Protože je to frontendová knihovna, používá se v ASP.NET Core balíčkovač Bower – ve Visual Studiu stačí kliknout pravým tlačítkem na projekt, vybrat Manage Bower Packages a vyhledat dropzone.

image

Dropzone je potřeba ručně přidat do souboru _Layout.cshtml, do sekce s ostatními skripty. Nejjednodušší je najít v Solution Exploreru soubor wwwroot\lib\dropzone\dist\dropzone.js a přetáhnout ho přímo na místo v kódu:


   
   
   
   

Totéž může být i v druhém prostředí (Staging, Production).

Dropzone dodává i vlastní CSS, tak jsem ho přidal taky (pro změnu do hlavičky _Layout.cshtml):


   
   
   
   

A na závěr je potřeba do souboru Views\Home\Index.cshtml přidat sekci, která Dropzone inicializuje:

@section scripts {

Upload do Azure

Teď konečně začneme hrnout soubory do Azure. První krok je přidat z NuGetu knihovnu WindowsAzure.Storage. Konkrétně její prerelease verzi (zobrazí se po zaškrtnutí volby „Include prerelease“ v NuGet Package Manageru). Tato knihovna se používá pro jakoukoliv práci s Blob Storage.

Následně si připravíme v IndexController.cs akci pro obsluhu odeslání formuláře se soubory:

[HttpPost]
async public Task Upload(ICollection files)
{
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse("[storageconnectionstring]");
    CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
    CloudBlobContainer container = blobClient.GetContainerReference("photos");
     foreach (var file in files)
    {
        using (var fileStream = file.OpenReadStream())
        {
            CloudBlockBlob blockBlob = container.GetBlockBlobReference(Guid.NewGuid().ToString() + ".jpg");
            blockBlob.Properties.ContentType = file.ContentType;
             byte[] fileBytes = new byte[fileStream.Length];
            await fileStream.ReadAsync(fileBytes, 0, fileBytes.Length);
            await blockBlob.UploadFromByteArrayAsync(fileBytes, 0, fileBytes.Length);
        }
    }
     return View("Index");
}

Pro upload samotný se používá metoda UploadFromByteArrayAsync, protože jednodušší UploadFromFileAsync v době výroby nefungovala…

Do metody automaticky vstupuje parametr files (není náhoda, že se jmenuje stejně jako hodnota paramName v konfiguraci Dropzone).

Metoda CloudStorageAccount.Parse přijímá jako parametr Connection String k Azure Storage Accountu, který chcete použít. Získává se například na portále Azure, případně ve Visual Studiu (Server Explorer –> Azure –> Storage). Typicky byste ho měli zadaný v konfiguračním souboru appsettings.json a tady ho načítali.

A ještě chybí formulář v HTML, který bude ve View Index.cshtml:

   
                   

Díky tomu, že formulář má class „dropzone“, skript ho najde a nahradí za komponentu Dropzone. Kdyby to z nějakého důvodu nevyšlo (např. zakázaný JavaScript v prohlížeči), zůstane nadále vidět div, který je uvnitř. Je důležité, aby se <input> jmenoval stejně jako parametr, který přijímá metoda Upload v kontroleru.

image

image

Základní podmínkou bylo, aby upload fungoval na mobilech s Windows, a Dropzone nezklamala na Windows 10 Mobile (Edge) ani na Windows Phone 8.1 (Internet Explorer).

Nasazení do Azure

Nasazení do Azure je potom jednoduché. Můžete zvolit Git nebo Web Deploy a klasický Publish dialog, jenom je potřeba dát pozor, aby web běžel na dostatečně velké instanci, jinak vyhodí chybu, že není dostatek místa na disku. Osvědčila se mi úroveň Standard, přičemž nebyl problém ji po nasazení zase stáhnout na Basic, případně Free.

Odkazy:

3 thoughts on “Azure Blob Storage a ASP.NET Core

  1. Danfer Habed López

    Hi there,

    Sorry as I don’t speak your language so have to write in English. Great sample you put here, helped me a lot with an issue I had as other samples didn’t include the line await fileStream.ReadAsync(fileBytes, 0, fileBytes.Length);. Without that uploading file gets it corrupted.

    Best regards,
    Danfer.

  2. Martin Šimeček Post author

    Thanks, I’m glad to see that the article helped you, Danfer!

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *