AzureStorageBlobExtensions.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. using Azure.Storage;
  2. using Azure.Storage.Blobs;
  3. using Azure.Storage.Blobs.Models;
  4. using Azure.Storage.Sas;
  5. using Microsoft.Extensions.DependencyInjection.Extensions;
  6. using System.Configuration;
  7. namespace HTEX.Complex.Service
  8. {
  9. public static class AzureStorageBlobExtensions
  10. {
  11. public static IServiceCollection AddAzureStorage(this IServiceCollection services, string connectionString, string name = "Default")
  12. {
  13. if (services == null) throw new ArgumentNullException(nameof(services));
  14. if (connectionString == null) throw new ArgumentNullException(nameof(connectionString));
  15. services.TryAddSingleton<AzureStorageFactory>();
  16. services.Configure<AzureStorageFactoryOptions>(name, o => { o.Name = name; o.StorageAccountConnectionString = connectionString; });
  17. return services;
  18. }
  19. /// <summary>
  20. /// 系统管理员 资源,题目关联,htex关联,学习活动学生上传文件关联,基本信息关联,教室平面图关联,评测冷数据关联
  21. /// "system": [ "res", "item", "htex", "task", "info", "room", "exam" ],
  22. /// 资源,题目关联,htex关联,学习活动学生上传文件关联,基本信息关联,教室平面图关联,评测冷数据关联
  23. /// "school": [ "res", "item", "htex", "task", "info", "room", "exam" ],
  24. /// 资源,题目关联,htex关联,学习活动关联,教师基本信息关联
  25. /// "teacher": [ "res", "item", "htex", "task", "info" ],
  26. /// 答案及学习活动上传的文件,学生基本信息关联
  27. ///"student": [ "stu/{studentId}/ans", "stu/{studentId}/task" ]
  28. /// </summary>
  29. /// <param name="name">容器名称</param>
  30. /// <param name="stream">文件内容的流</param>
  31. /// <param name="folder">业务文件夹</param>
  32. /// <param name="fileName">文件名</param>
  33. /// <param name="contentTypeDefault">是否存放文件后缀对应的contentType</param>
  34. /// <returns></returns>
  35. public static async Task<(string blobName ,string url )> UploadFileByContainer(this BlobContainerClient blobContainer, Stream stream, string root, string blobpath, bool contentTypeDefault = true)
  36. {
  37. //BlobContainerClient blobContainer = azureStorage.GetBlobContainerClient(name.ToLower().Replace("#", "")); //blobClient.GetContainerReference(groupName);
  38. Uri url = blobContainer.Uri;
  39. var blockBlob = blobContainer.GetBlobClient($"{root}/{blobpath}");
  40. string content_type = "application/octet-stream";
  41. if (!contentTypeDefault)
  42. {
  43. string fileext = blobpath.Substring(blobpath.LastIndexOf(".") > 0 ? blobpath.LastIndexOf(".") : 0);
  44. ContentTypeDict.dict.TryGetValue(fileext, out string contenttype);
  45. if (!string.IsNullOrEmpty(contenttype))
  46. {
  47. content_type = contenttype;
  48. }
  49. }
  50. await blockBlob.UploadAsync(stream, true);
  51. blockBlob.SetHttpHeaders(new BlobHttpHeaders { ContentType = content_type });
  52. return (blockBlob.Name,blockBlob.Uri.ToString());
  53. }
  54. public static async Task<string> UploadFileByContainer(this BlobContainerClient blobContainer, string json, string root, string blobpath, bool contentTypeDefault = true)
  55. {
  56. // string groupName =folder;
  57. //BlobContainerClient blobContainer = azureStorage.GetBlobContainerClient(name.ToLower().Replace("#", "")); //blobClient.GetContainerReference(groupName);
  58. var blockBlob = blobContainer.GetBlobClient($"{root}/{blobpath}");
  59. string content_type = "application/octet-stream";
  60. if (!contentTypeDefault)
  61. {
  62. string fileext = blobpath.Substring(blobpath.LastIndexOf(".") > 0 ? blobpath.LastIndexOf(".") : 0);
  63. ContentTypeDict.dict.TryGetValue(fileext, out string contenttype);
  64. if (!string.IsNullOrEmpty(contenttype))
  65. {
  66. content_type = contenttype;
  67. }
  68. }
  69. byte[] bytes = System.Text.Encoding.Default.GetBytes(json);
  70. Stream streamBlob = new MemoryStream(bytes);
  71. await blockBlob.UploadAsync(streamBlob, true);
  72. blockBlob.SetHttpHeaders(new BlobHttpHeaders { ContentType = content_type });
  73. return blockBlob.Uri.ToString();
  74. }
  75. /// <summary>
  76. /// 取得Blob SAS (有效期預設一天)
  77. /// </summary>
  78. /// <param name="containerName">容器名稱</param>
  79. /// <param name="blobName"></param>
  80. /// <param name="blobSasPermissions"></param>
  81. /// <param name="name"></param>
  82. /// <returns></returns>
  83. public static BlobAuth GetBlobSasUriRead(this BlobContainerClient blobContainer,IConfiguration _configuration , string containerName, string blobName, string name = "Default")
  84. {
  85. try
  86. {
  87. var ConnectionString = name.Equals("Default") ? _configuration.GetSection("Azure:Storage:ConnectionString").Value : _configuration.GetSection("Azure:Storage:ConnectionString-Test").Value;
  88. var keys = ParseConnectionString(ConnectionString);
  89. var accountname = keys["AccountName"];
  90. var accountkey = keys["AccountKey"];
  91. var endpoint = keys["EndpointSuffix"];
  92. DateTimeOffset dateTime = DateTimeOffset.UtcNow.Add(new TimeSpan(365 * 99, 0, 15, 0));
  93. long time = dateTime.ToUnixTimeMilliseconds();
  94. var blobSasBuilder = new BlobSasBuilder
  95. {
  96. StartsOn = DateTimeOffset.UtcNow.Subtract(new TimeSpan(0, 15, 0)),
  97. ExpiresOn = dateTime,
  98. BlobContainerName = containerName.ToLower(),
  99. BlobName = blobName
  100. };
  101. blobSasBuilder.SetPermissions(BlobSasPermissions.Read);
  102. var sskc = new StorageSharedKeyCredential(accountname, accountkey);
  103. BlobSasQueryParameters sasQueryParameters = blobSasBuilder.ToSasQueryParameters(sskc);
  104. UriBuilder fullUri = new UriBuilder()
  105. {
  106. Scheme = "https",
  107. Host = $"{accountname}.blob.{endpoint}",
  108. Path = $"{containerName.ToLower()}/{blobName}",
  109. Query = sasQueryParameters.ToString()
  110. };
  111. return new BlobAuth { url = fullUri.Uri.ToString(), sas = sasQueryParameters.ToString(), timeout = time };
  112. // return fullUri.Uri.ToString();
  113. }
  114. catch
  115. {
  116. return null;
  117. }
  118. }
  119. public static async Task<List<string>> List(this BlobContainerClient client, string prefix = null)
  120. {
  121. try
  122. {
  123. List<string> items = new List<string>();
  124. await foreach (BlobItem item in client.GetBlobsAsync(BlobTraits.None, BlobStates.None, prefix))
  125. {
  126. items.Add(item.Name);
  127. }
  128. return items;
  129. }
  130. catch
  131. {
  132. return null;
  133. }
  134. }
  135. public static Dictionary<string, string> ParseConnectionString(string connectionString)
  136. {
  137. var d = new Dictionary<string, string>();
  138. foreach (var item in connectionString.Split(';', StringSplitOptions.RemoveEmptyEntries))
  139. {
  140. var a = item.IndexOf('=');
  141. d.Add(item.Substring(0, a), item.Substring(a + 1));
  142. }
  143. return d;
  144. }
  145. public class BlobAuth
  146. {
  147. public string url { get; set; }
  148. public string sas { get; set; }
  149. public long timeout { get; set; }
  150. public string name { get; set; }
  151. }
  152. }
  153. }