iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 6
1
Everything on Azure

三十天.NET❤️Azure漸進式開發專案系列 第 6

三十天.NET與Azure漸進式開發專案(6):替換使用Azure Storage Blob保存圖片

前一篇文章提到上傳圖片到公開圖床,雖然有免費優點,但一不小心上傳重要資料等於公告全世界。所以接下來介紹Azure提供的檔案服務(Azure Blob Storage)服務取代公開圖床,可以細部控管檔案。


【第一步】建立帳號、建立Blog容器
2018-10-11.22.17.11-image.png
填寫基本資料,一開始測試開發使用基本就夠用了
2018-10-11.22.17.18-image.png
點選"儲存體帳戶" -> 建立"容器"
2018-10-11.22.17.21-image.png

【第二步】在容器使用上傳檔案方式上傳圖片,接著可以在線上檢視圖片,這步驟也是等一下要寫的程式邏輯。
2018-10-11.22.17.29-image.png

假如上傳到資安、重要檔案,或是不需要的檔案可以選取刪除
2018-10-11.22.17.35-image.png

【第三步】使用SDK改寫昨天上傳Imgur專案,NuGet安裝WindowsAzure.Storage

Install-Package WindowsAzure.Storage -Version 9.3.2  

程式邏輯很簡單

  1. 讀取azure web app圖片目錄下所有檔案
  2. 上傳圖片到Storage
  3. 更新Blog的文章圖片路徑,接著移到上傳成功資料夾

因為每個技術都有使用的情境,這邊特別寫藉由switch enum讓讀者決定要上傳Imgur或是使用Storage,更換UploadType值就可以達到效果。

using Imgur.API.Authentication.Impl;  
using Imgur.API.Endpoints.Impl;  
using Microsoft.WindowsAzure.Storage;  
using Microsoft.WindowsAzure.Storage.Blob;  
using System;  
using System.IO;  
using System.Threading.Tasks;  
  
namespace WebJobUploadImagesToImgur  
{  
    class Program  
    {  
        enum UploadType  
        {  
            Imugr, AzureSTBlog  
        }  
  
        private static readonly UploadType uploadType = UploadType.AzureSTBlog;  
        private static readonly string rootPaht = "D:/home/site/wwwroot/wwwroot/";  
        static void Main(string[] args)  
        {  
            Console.WriteLine("Start");  
  
            //獲取目錄下所有png圖片  
            var unUploadFloder = Path.Combine(rootPaht, "Posts/files");  
            var uploadedFloder = Path.Combine(rootPaht, "Posts/UploadedImgs");  
            System.IO.Directory.CreateDirectory(uploadedFloder);  
            var filePaths = Directory.GetFiles(rootPaht, "*.png", SearchOption.AllDirectories);  
  
            //上傳圖片到圖床,更新Blog的文章圖片路徑,接著移到上傳成功資料夾  
            foreach (var path in filePaths)  
            {  
                string filename = Path.GetFileName(path);  
                byte[] photo = File.ReadAllBytes(path);  
                string imgurPath = string.Empty;  
  
                //決定哪種模式上傳圖片(Imgur、AzureSTBlob)  
                switch (uploadType)  
                {  
                    case UploadType.AzureSTBlog: imgurPath = UploadAzureStorageBlogImageByBytesAsync(photo).GetAwaiter().GetResult(); break;  
                    case UploadType.Imugr: imgurPath = UploadImgurImageByBytesAsync(photo).GetAwaiter().GetResult(); break;  
                }  
  
                string moveToPath = Path.Combine(uploadedFloder, filename);  
                Console.WriteLine($"{photo.ToString()} UploadTo {imgurPath} And Move To {moveToPath}");  
  
                if (ChangePostImgPathByImgurPath(path, imgurPath).GetAwaiter().GetResult())  
                {  
                    Console.WriteLine("Change Success");  
                    File.Move(path, moveToPath);  
                }  
            }  
            Console.WriteLine("End");  
  
        }  
  
        private static async Task<string> UploadImgurImageByBytesAsync(byte[] bytes)  
        {  
            var client = new ImgurClient("clientId", "clientSecret");   
            var endpoint = new ImageEndpoint(client);  
            return (await endpoint.UploadImageBinaryAsync(bytes)).Link;  
        }  
  
        private static async Task<string> UploadAzureStorageBlogImageByBytesAsync(byte[] bytes)  
        {  
            const string connectionString = @"替換你的連線字串";  
            const string containerName = @"替換你的容器名稱";  
            string localFileName = $"{Guid.NewGuid().ToString()}.png";  
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);  
  
            CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();  
            CloudBlobContainer container = blobClient.GetContainerReference(containerName);  
            CloudBlockBlob cloudBlockBlob = container.GetBlockBlobReference(localFileName);  
            await cloudBlockBlob.UploadFromByteArrayAsync(bytes, 0, bytes.Length);  
  
            var azureSTUri = Path.Combine(container.StorageUri.PrimaryUri.AbsoluteUri, localFileName);  
            return await Task.FromResult(azureSTUri);  
        }  
  
        private static async Task<bool> ChangePostImgPathByImgurPath(string path, string imgurPath)  
        {  
            return /*更新文章邏輯*/  
        }  
    }  
}  
  

接著運行程式,成功後可以看到圖片上傳到Azure Storage 容器
2018-10-11.22.17.48-image.png

【最後一步】給別人讀取驗證
這時候給別人讀取讀取上傳連結的時候會發現錯誤ResourceNotFount,這時候會疑惑奇怪不是有上傳成功嗎?
2018-10-11.22.18.01-image.png
那是因為"公用存取層級"Storage預設是"私人"
我們需要去修改存取原則,開通"匿名讀取權限"
2018-10-11.22.18.08-image.png
接著重新給別人查看圖片的時候,就是正常畫面了~~~
2018-10-11.22.18.32-image.png


結論

Azure Storage Blog除了當圖床使用,還可以做特殊操作像是:
圖片只有七天公開週期,時間一到就不公開,指定IP內才能讀取圖片..等等,可以細部操作我們想要的結果,加上SDK容易又快速地開發


上一篇
三十天.NET與Azure漸進式開發專案(5):WebJob+C#做排程器,更新server圖片到圖床
下一篇
三十天.NET與Azure漸進式開發專案(7): Azure SQL Database 使用、概念
系列文
三十天.NET❤️Azure漸進式開發專案30

尚未有邦友留言

立即登入留言