当前位置 博文首页 > Grant_Allen:Azure Functions(二)集成 Azure Blob Storage 存
上一篇文章有介绍到什么是 SeverLess ,ServerLess 都有哪些特点,以及多云环境下 ServerLess 都有哪些解决方案。在这众多解决方案中就包括 Function App(Azure 下的ServerLess),今天我们结合之前所讲的 Azure Functions 以及 Azure Blob Storage 的相关知识,从实践出发,再次回顾之前的知识点,以下是构想的基础资源架构图
--------------------Azure Functions 系列--------------------
Azure Portal,点击“Create a resource”,搜索框中输入 “Function App”。
点击 “Create”,创建 Function App
输入相关参数:
Resource Group 选择创建新的资源组:“Web_Test_Functions_RG”
Function App name:“cnbateblogweb”
Publicsh 发布方式:Code(代码)
Runtime stack 选择:“.NET”
Version:“3.1”
Region 选择:“East Asia”
点击 “Next:Hosting” 设置承载
接下来 “Hosting” 相关参数
Storage:当我们在创建函数应用时,必须创建或链接到支持的Blob,Queue,Table Storage 的常规用途的 Azure 存储账号
Storage Account 选择创建新的:cnbatestorageaccount
Operation system 选择:“Windows”
Plan 选择:Consumption(ServerLess) 消耗(无服务器)
点击 “Next:Monitoring >” 设置监视信息
接下来我们需要自身的需要 选择是否开启 Application Insights(用于在应用程序中提供详细的可观测性)
Enable Application Insights:“Yes”
Application Insights 选择创建新的:“cnbateblogweb”
点击 “Review + create”,创建预览。
预校验完成后,点击 “Create” 进行创建。
稍等片刻,我们回到 “Web_Test_Functions_RG” 这个资源组可以查看到我们创建好的资源
最后,我们需要创建用于保存图片的 Blob Container
选择 “Blob service =》Container”,点击箭头所指的 “+ Container”
输入创建新的容器的相关参数:
Name:“picturecontainer”
Public access level 选择默认:“Private(no anonymous access)”
点击 “Create”
创建完成后,就可以在当前页面上看到 “picturecontainer” 的 Blob Container
使用程序包管理器控制台进行安装
Install-Package Azure.Storage.Blobs -Version 12.8.0 Install-Package Microsoft.AspNetCore.StaticFiles -Version 2.2.0 Install-Package Microsoft.Azure.Functions.Extensions -Version 1.1.0 Install-Package Microsoft.Extensions.DependencyInjection -Version 5.0.1 Install-Package Microsoft.NET.Sdk.Functions -Version 3.0.11
这里要注意的是 "Microsoft.Extensions.DependencyInjection"、"Microsoft.NET.Sdk.Functions"、"Microsoft.Azure.Functions.Extensions" ,主要是想在 Azure Functions 中使用一俩注入(DI)
大家可以自行参考 Use dependency injection in .NET Azure Functions
1 public interface IBlobService 2 { 3 Task UploadImagesBlobAsync(string filePath, string filename); 4 5 Task UploadFileBlobAsync(string filePath, string filename); 6 7 Task UploadContentBlobAsync(string content, string filename); 8 }
1 public class BlobService : IBlobService 2 { 3 private readonly BlobServiceClient _blobServiceClient; 4 5 public BlobService(BlobServiceClient blobServiceClient) 6 { 7 this._blobServiceClient = blobServiceClient; 8 } 9 10 #region 02,抓取网络图片,根据图片URL和图片名称+async Task UploadFileBlobAsync(string filePath, string filename) 11 /// <summary> 12 /// 上传图片流,根据图片URL和图片名称 13 /// </summary> 14 /// <param name="filePath">图片URL</param> 15 /// <param name="filename">图片名称</param> 16 /// <returns></returns> 17 public async Task UploadImagesBlobAsync(string filePath, string filename) 18 { 19 var containerClient = _blobServiceClient.GetBlobContainerClient("picturecontainer"); 20 var blobClient = containerClient.GetBlobClient(filename); 21 22 #region 获取图片流 23 var response = FeatchPictureClient.GetWebResponse(filePath); 24 var bytes = FeatchPictureClient.GetResponseStream(response); 25 await using var memoryStream = new MemoryStream(bytes); 26 27 //上传图片流 28 await blobClient.UploadAsync(memoryStream, new BlobHttpHeaders() { ContentType = filename.GetContentType() }); 29 #endregion 30 } 31 #endregion 32 33 #region 03,上传图片,根据文件路径和文件名称+async Task UploadFileBlobAsync(string filePath, string filename) 34 /// <summary> 35 /// 上传图片流,根据文件路径和文件名称 36 /// </summary> 37 /// <param name="filePath">文件路径</param> 38 /// <param name="filename">文件名称</param> 39 /// <returns></returns> 40 public async Task UploadFileBlobAsync(string filePath, string filename) 41 { 42 var containerClient = _blobServiceClient.GetBlobContainerClient("picturecontainer"); 43 var blobClient = containerClient.GetBlobClient(filename); 44 await blobClient.UploadAsync(filePath, new BlobHttpHeaders { ContentType = filePath.GetContentType() }); 45 } 46 #endregion 47 48 #region 04,上传文件内容,根据文件内容和文件名称+async Task UploadContentBlobAsync(string content, string filename) 49 /// <summary> 50 /// 上传文件流,根据文件内容和文件名称 51 /// </summary> 52 /// <param name="content">文件内容</param> 53 /// <param name="filename">文件名称</param> 54 /// <returns></returns> 55 public async Task UploadContentBlobAsync(string content, string filename) 56 { 57 var containerClient = _blobServiceClient.GetBlobContainerClient("picturecontainer"); 58 var blobClient = containerClient.GetBlobClient(filename); 59 var bytes = Encoding.UTF8.GetBytes(content); 60 await using var memoryStream = new MemoryStream(bytes); 61 await blobClient.UploadAsync(memoryStream, new BlobHttpHeaders() { ContentType = filename.GetContentType() }); 62 } 63 #endregion 64 65 }
1 public class UpLoadTrigger 2 { 3 private readonly IBlobService _blobSergvice; 4 5 public UpLoadTrigger(IBlobService blobSergvice) 6 { 7 _blobSergvice = blobSergvice; 8 } 9 10 [FunctionName("UpLoadTrigger")] 11 public async Task<IActionResult> Run( 12 [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] BlobViewModel req, 13 ILogger log) 14 { 15 log.LogInformation("C# HTTP trigger function processed a request."); 16 17 await _blobSergvice.UploadImagesBlobAsync(req.FilePath, req.FileName); 18 return new OkObjectResult("ok"); 19 } 20 }
1 public static class FileExtensions 2 { 3 private static readonly FileExtensionContentTypeProvider provider = new FileExtensionContentTypeProvider(); 4 5 public static string GetContentType(this string fileName) 6 { 7 if (!provider.TryGetContentType(fileName, out var contentType)) 8 { 9 contentType = "application/octet-stream"; 10 } 11 return contentType; 12 } 13 }
1 public class FeatchPictureClient 2 { 3 /// <summary> 4 /// 获取URL响应对象 5 /// </summary> 6 /// <param name="url"></param> 7 /// <returns></returns> 8 public static WebResponse GetWebResponse(string url) 9 { 10 System.Net.HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url); 11 request.CookieContainer = new CookieContainer(); 12 request.KeepAlive = true; 13 WebResponse res = request.GetResponse(); 14 return res; 15 } 16 17 public static byte[] GetResponseStream(WebResponse response) 18 { 19 Stream smRes = response.GetResponseStream(); 20 byte[] resBuf = new byte[10240]; 21 int nReaded = 0; 22 MemoryStream memSm = new MemoryStream(); 23 while ((nReaded = smRes.Read(resBuf, 0, 10240)) != 0) 24 { 25 memSm.Write(resBuf, 0, nReaded); 26 } 27