iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 6
2
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
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
tsai_ithome
iT邦新手 5 級 ‧ 2021-08-29 16:14:58

大大您好~
借這篇發問,最近在測試使用AZURE~有些問題想請教~
問題1.請問AZURE免費方案,建立靜態 Web 應用程式,有設定連接GITHUB這個部份沒問題,
但這時他的網址是由AZURE是他自己產生的很長一串嗎?

問題2.另外
如果是Azure App Service 建立的靜態網站就可以有自己指定名稱的網址(例如:ABCTEST)
網址就有可能是→ https://ABCTEST.azurewebsites.net (左列網址是舉例用,實際連不到)

有參考這篇↓
https://docs.microsoft.com/zh-tw/azure/app-service/quickstart-html

但無法更新本地端的 js/ css/ img/ 檔案
不知道可否將整個目錄更新上傳?

因為照他的範例,只能在AZURE內的Azure Cloud Shell下指令的話(不是很好用)
只能改改很簡單的一些字,只能更新HTML檔
AZURE範例只有這個↓
az webapp up --location westeurope --name <app_name> --html

問題3.有沒有可能像大大這篇說的把Azure Storage Blob當放置圖片及CSS或JS的位置,
當在Azure App Service建立的靜態網站將HTML內的位置都修改為Azure Storage Blob的位置?
達到 "問題2" 的目的?總而言之~我只是想要更新圖檔~CSS~JS+HTML~
還是會有解決方式嗎?XD

還是這是免費方案的關係嗎XD
以上謝謝~~~^^

我要留言

立即登入留言