Hej Wam. Trzeba trochę odkurzyć projekt, a z racji, że w chwili pisania tego artykułu wylądowałem na ławce, postanowiłem się podszkolić z wiedzy, która przyda się każdemu. Mi się przydała do mojego projektu.
Nie jest też to droga usługa, przynajmniej na potrzebę usług takich jak galeria na stronie.
W tej części nie tylko opowiem Wam na temat założenia Storage Account, ale także jak obsłużyć “Bloby”.
Przy okazji, to już 2 lata od regularnego pisania w ramach DSP. Dzisiaj nie dałbym radę pisać 2x tygodniowo wpisów jak wtedy.
Azure Storage
Zacznę od tego, że usługa Azure Storage, to zestaw przestrzeni dla plików (Blob i File Storage). Mała baza danych Table Storage, a także kolejki czyli Queue (długo nie wiedziałem jak to wymówić bez łamania języka) Storage.
Warto jeszcze dodać, że usługi te świetnie współgrają z usługami serverless od Azure.
Tworzenie usługi
Do rozpoczęcia pracy z BlobStorage potrzebujemy założyć Azure Storage. Jeśli nie posiadasz subskrypcji Azure, na visualstudio.net po założeniu konta i przejściu do my benefits/moje korzyści można dostać za darmo roczną.Wystarczy do sandboxowania, a nawet prostej strony.
Po zalogowaniu na portal Azure klikamy na Create a Resource a potem Storage Accounts i stwórzcie swoją usługę.
Następnie po wejściu na usługę przechodzimy do Access Key i kopiujemy Connection strings z Key1, np. do naszego appsettings, zmiennych systemowych czy key vault.

No to zaczynamy kod
Czekaliście na to 🙂
Zróbmy to bardziej elegancko, bo dobre nawyki są docenione przez przyszłych lub obecnych pracodawców i kolegów z teamu.
Zacznijmy od interfejsu do naszego repo.
Interfejs i przygotowanie
public interface IBlobStorage { Task<BlobItem> Create(BlobItem item); Task<Result> Update(BlobItem item); Task<Result> Remove(string name, string folder); Task<BlobItem> Get(string name, string folder); Task<IEnumerable<BlobItem>> GetList(string folder); }
Oraz Data Modelu, na którym oprzemy nasze działania
public class BlobItem { public string Container { get; set; } public Uri Uri { get; set; } public Uri StorageUri { get; set; } public Stream Stream { get; set; } public string Name { get; set; } }
Zanim zaczniemy, należy pobrać z nugeta paczkę Microsoft.WindowsAzure.Storage.Blob
W konstruktorze tworzymy instancję Blob Client i Blob Accounts
private readonly CloudBlobClient BlobClient; public BlobStorage(IConfiguration configuration) { var storageAccount = CloudStorageAccount.Parse(configuration[“BlobStorage”]); BlobClient = storageAccount.CreateCloudBlobClient(); }
A następnie obiekt, który tworzy i zarządza naszą kolekcją, czyli kontener:
private CloudBlobContainer GetContainer(string folder) { var container = BlobClient.GetContainerReference(folder); container.CreateIfNotExistsAsync().Wait(); return container; }
Nazwa folderu, czy kontera określa naszą ścieżkę oraz pozwoli zrobić porządek w plikach oraz zarządzaniu uprawnieniami do nich. Ważne, by ustawić np. w panelu dostępność:
- Private : tylko z poziomu kodu mamy dostęp.
- Container: Użytkownik może widzieć wszystkie pliki w kolekcji
- Blob: Użytkownik może widzieć plik, gdy wejdzie na bezpośredni link do niego
Przy okazji kreator do tworzenia BlobItem
private static BlobItem GenerateBlob(CloudBlockBlob blob) { return new BlobItem { Container = blob.Container.Name, StorageUri = blob.StorageUri.PrimaryUri, Uri = blob.Uri, Name = blob.Name }; }
Tworzenie CRUD
To teraz przejdźmy do stworzenia standardowych CRUD Metod dla naszego serwisu:
Create
public async Task<BlobItem> Create(BlobItem item) { var container = GetContainer(item.Container); var blob = container.GetBlockBlobReference(item.Name); await blob.UploadFromStreamAsync(item.Stream); item.Uri = blob.Uri.AbsoluteUri; return item; }
Get
public async Task<IEnumerable<BlobItem>> GetList(string folder) { var container = GetContainer(folder); var blob = await container.ListBlobsSegmentedAsync(null); return blob.Results.Select(p =>new BlobItem { StorageUri = p.StorageUri.PrimaryUri, Uri = p.Uri, Container = p.Container.Name }); } public async Task<BlobItem> Get(string name, string folder) { var container = GetContainer(folder); var blob = container.GetBlockBlobReference(name); return GenerateBlob(blob); }
Jeśli potrzeba, z BlockBlobReference możemy też pobrać Streama z danymi, które potem możemy zapisać do pliku czy pamięci. Na potrzeby swojej strony, potrzebowałem tylko url do pliku.
Update
public async Task<Result> Update(BlobItem item) { try { var container = GetContainer(item.Container); var blob = container.GetBlockBlobReference(item.Name); await blob.UploadFromStreamAsync(item.Stream); return Result.Success; } catch (Exception) { return Result.Failed; } }
Podobnie jak create, tylko uploadujemy plik do istniejącego juz bloba.
Delete
A teraz czyścimy
public async Task<Result> Remove(string name, string folder) { try { var container = GetContainer(folder); var blob = container.GetBlockBlobReference(name); await blob.DeleteAsync(); return Result.Success; } catch (Exception) { return Result.Failed; } }
Czyli szukamy naszego bloba i prosty delete 🙂
Podsumowanie
To by było tyle na ten wpis. Nauczyliście się tworzyć serwis w azure oraz obsługiwać go.
Zapraszam do regularnego czytania oraz opinii.
P.s Kod dostępny na GitHub – aluspl/AzureSamples: Azure samples, for upskill and blog i na GitHub – aluspl/LifeLike: CMS System based on net core and microservices