using TEAMModelOS.SDK.Module.AzureBlob.Configuration; using TEAMModelOS.SDK.Module.AzureBlob.Container; using TEAMModelOS.SDK.Module.AzureBlob.Interfaces; using Microsoft.WindowsAzure.Storage; using Microsoft.WindowsAzure.Storage.Blob; using System; using System.Collections.Generic; using System.IO; using System.Net.Http.Headers; using System.Threading.Tasks; using TEAMModelOS.SDK.Helper.Security.AESCrypt; using TEAMModelOS.SDK.Context.Exception; using Microsoft.AspNetCore.Http; using TEAMModelOS.SDK.Extension.SnowFlake; using TEAMModelOS.SDK.Context.Constant; using TEAMModelOS.SDK.Helper.Common.JsonHelper; using TEAMModelOS.SDK.Helper.Security.ShaHash; using Microsoft.Extensions.Configuration; using TEAMModelOS.SDK.Context.Configuration; using Microsoft.AspNetCore.Hosting; namespace TEAMModelOS.SDK.Module.AzureBlob.Implements { public class AzureBlobDBRepository : IAzureBlobDBRepository { public CloudBlobClient blobClient; public CloudBlobContainer blobContainer; public AzureBlobOptions _options; public IConfiguration Configuration { get; } public AzureBlobDBRepository(IConfiguration configuration, IWebHostEnvironment env, AzureBlobOptions options) { Configuration = configuration; BaseConfigModel.SetBaseConfig(Configuration, env.ContentRootPath, env.WebRootPath); _options = options; if (!string.IsNullOrEmpty(options.ConnectionString)) { blobClient = BlobClientSingleton.getInstance(options.ConnectionString).GetBlobClient(); } else { throw new BizException("请设置正确的AzureBlob文件存储配置信息!"); } } public AzureBlobDBRepository() { // _connectionString = BaseConfigModel.Configuration["AppSettings:Azure:TableStorageConnection"]; } //private async Task InitializeBlob(string container) //{ ////https://teammodelstorage.blob.core.chinacloudapi.cn/wechatfilescontainer // if (blobContainer == null) // { // // Type t = typeof(T); // //若要将权限设置为仅针对 blob 的公共读取访问,请将 PublicAccess 属性设置为 BlobContainerPublicAccessType.Blob。 // //要删除匿名用户的所有权限,请将该属性设置为 BlobContainerPublicAccessType.Off。 // blobContainer = blobClient.GetContainerReference("wechatfilescontainer"); // // await blobContainer.CreateIfNotExistsAsync(); // // BlobContainerPermissions permissions = await blobContainer.GetPermissionsAsync(); // // permissions.PublicAccess = BlobContainerPublicAccessType.Blob; // // await blobContainer.SetPermissionsAsync(permissions); // } // //await UploadFiles(null, new FileContainer() ); //} public async Task> UploadFiles(IFormFile[] file,string fileSpace= "common" , bool contentTypeDefault = false) { string groupName = fileSpace+"/" +DateTime.Now.ToString("yyyyMMdd"); string newFileName = DateTime.Now.ToString("yyyyMMddHHmmss"); // await InitializeBlob(DateTime.Now.ToString("yyyyMMdd")); blobContainer = blobClient.GetContainerReference( groupName); //var serviceProperties = await blobClient.GetServicePropertiesAsync(); //var corsSettings = serviceProperties.Cors; //var corsRule = corsSettings.CorsRules.FirstOrDefault( // o => o.AllowedOrigins.Contains("http://localhost:3904"));//设置你自己的服务器地址 //if (corsRule == null) //{ // //Add a new rule. // corsRule = new CorsRule() // { // AllowedHeaders = new List { "x-ms-*", "content-type", "accept" }, // AllowedMethods = CorsHttpMethods.Put| CorsHttpMethods.Head | CorsHttpMethods.Post | CorsHttpMethods.Merge | CorsHttpMethods.Get,//Since we'll only be calling Put Blob, let's just allow PUT verb // AllowedOrigins = new List { "http://localhost:3904" },//This is the URL of our application. // ExposedHeaders = { }, // MaxAgeInSeconds = 1 * 60 * 60,//Let the browswer cache it for an hour // }; // corsSettings.CorsRules.Add(corsRule); // //Save the rule // await blobClient.SetServicePropertiesAsync(serviceProperties); //} StorageUri url = blobContainer.StorageUri; List list = new List(); foreach (FormFile f in file) { string[] names = f.FileName.Split("."); string name = ""; for (int i = 0; i < names.Length-1; i++) { name = name + names[i]; } if (names.Length <= 1) { name = f.FileName + "_" + newFileName; } else { name = name + "_" + newFileName + "." + names[names.Length - 1]; } string fileext = f.FileName.Substring(f.FileName.LastIndexOf(".")>0? f.FileName.LastIndexOf("."):0); var parsedContentDisposition = ContentDispositionHeaderValue.Parse(f.ContentDisposition); var filename = Path.Combine(parsedContentDisposition.FileName.Trim('"')); var blockBlob = blobContainer.GetBlockBlobReference(name); if (!contentTypeDefault) { ContentTypeDict.dict.TryGetValue(fileext, out string content_type); if (!string.IsNullOrEmpty(content_type)) { blockBlob.Properties.ContentType = content_type; } } await blockBlob.UploadFromStreamAsync(f.OpenReadStream()); string sha1= ShaHashHelper.GetSHA1(f.OpenReadStream()); AzureBlobModel model = new AzureBlobModel(f, _options.Container, groupName, name) { BlobUrl = url.PrimaryUri.ToString().Split("?")[0] + "/" + name, Sha1Code = sha1 }; list.Add(model); } return list; } public async Task UploadPath(string path, string fileSpace = "common" , bool contentTypeDefault = false) { string groupName = fileSpace + "/" + DateTime.Now.ToString("yyyyMMdd"); string newFileName = DateTime.Now.ToString("HHmmssfffffff"); blobContainer = blobClient.GetContainerReference(groupName); StorageUri url = blobContainer.StorageUri; FileInfo file = new FileInfo(path); string[] names = file.Name.Split("."); string name = ""; for (int i = 0; i < names.Length - 1; i++) { name = name + names[i]; } if (names.Length <= 1) { name = file.Name + "_" + newFileName; } else { name = name + "_" + newFileName + "." + names[names.Length - 1]; } string fileext = file.Name.Substring(file.Name.LastIndexOf(".") > 0 ? file.Name.LastIndexOf(".") : 0); // var parsedContentDisposition = ContentDispositionHeaderValue.Parse("form-data; name=\"files\"; filename=\"" + file.Name + "\""); var blockBlob = blobContainer.GetBlockBlobReference(name); string content_type = "application/octet-stream"; if (!contentTypeDefault) { ContentTypeDict.dict.TryGetValue(fileext, out string contenttype); if (!string.IsNullOrEmpty(contenttype)) { blockBlob.Properties.ContentType = contenttype; content_type = contenttype; } else { blockBlob.Properties.ContentType = content_type; } } else { blockBlob.Properties.ContentType = content_type; } await blockBlob.UploadFromFileAsync(path); //var provider = new FileExtensionContentTypeProvider(); //var memi = provider.Mappings[fileext]; AzureBlobModel model = new AzureBlobModel(file, _options.Container, groupName, name , content_type) { Sha1Code=ShaHashHelper.GetSHA1(file.Create()), BlobUrl = url.PrimaryUri.ToString().Split("?")[0] + "/" + name }; return model; } public async Task UploadText(string fileName, string text, string fileSpace = "common", bool contentTypeDefault = true) { string groupName = fileSpace + "/" + DateTime.Now.ToString("yyyyMMdd"); string newFileName = DateTime.Now.ToString("HHmmssfffffff"); blobContainer = blobClient.GetContainerReference(groupName); StorageUri url = blobContainer.StorageUri; //FileInfo file = new FileInfo(path); string[] names = fileName.Split("."); string name = ""; for (int i = 0; i < names.Length - 1; i++) { name = name + names[i]; } if (names.Length <= 1) { name = fileName + "_" + newFileName; } else { name = name + "_" + newFileName + "." + names[names.Length - 1]; } var blockBlob = blobContainer.GetBlockBlobReference(name); // var parsedContentDisposition = ContentDispositionHeaderValue.Parse("form-data; name=\"files\"; filename=\"" + file.Name + "\""); string fileext = fileName.Substring(fileName.LastIndexOf(".") > 0 ? fileName.LastIndexOf(".") : 0); string content_type = "application/octet-stream"; if (!contentTypeDefault) { ContentTypeDict.dict.TryGetValue(fileext, out string contenttype); if (!string.IsNullOrEmpty(contenttype)) { blockBlob.Properties.ContentType = contenttype; content_type = contenttype; } else { blockBlob.Properties.ContentType = content_type; } } else { blockBlob.Properties.ContentType = content_type; } await blockBlob.UploadTextAsync(text); byte[] bytes = System.Text.Encoding.Default.GetBytes(text); //var provider = new FileExtensionContentTypeProvider(); //var memi = provider.Mappings[fileext]; AzureBlobModel model = new AzureBlobModel(fileName, _options.Container, groupName, name, content_type, bytes.Length) { Sha1Code = ShaHashHelper.GetSHA1(bytes), BlobUrl = url.PrimaryUri.ToString().Split("?")[0] + "/" + name }; return model; } public async Task UploadObject(string fileName,object obj, string fileSpace = "common", bool contentTypeDefault =true) { string groupName = fileSpace + "/" + DateTime.Now.ToString("yyyyMMdd"); string newFileName = DateTime.Now.ToString("HHmmssfffffff"); blobContainer = blobClient.GetContainerReference(groupName); StorageUri url = blobContainer.StorageUri; //FileInfo file = new FileInfo(path); string[] names = fileName.Split("."); string name = ""; for (int i = 0; i < names.Length - 1; i++) { name = name + names[i]; } if (names.Length <= 1) { name = fileName + "_" + newFileName; } else { name = name + "_" + newFileName + "." + names[names.Length - 1]; } var blockBlob = blobContainer.GetBlockBlobReference(name); // var parsedContentDisposition = ContentDispositionHeaderValue.Parse("form-data; name=\"files\"; filename=\"" + file.Name + "\""); string fileext = fileName.Substring(fileName.LastIndexOf(".") > 0 ? fileName.LastIndexOf(".") : 0); string content_type = "application/octet-stream"; if (!contentTypeDefault) { ContentTypeDict.dict.TryGetValue(fileext, out string contenttype); if (!string.IsNullOrEmpty(contenttype)) { blockBlob.Properties.ContentType = contenttype; content_type = contenttype; } else { blockBlob.Properties.ContentType = content_type; } } else { blockBlob.Properties.ContentType = content_type; } string objStr = obj.ToJsonAbs(); await blockBlob.UploadTextAsync(objStr); //var provider = new FileExtensionContentTypeProvider(); //var memi = provider.Mappings[fileext]; byte[] bytes = System.Text.Encoding.Default.GetBytes(objStr); AzureBlobModel model = new AzureBlobModel(fileName, _options.Container, groupName, name, content_type , bytes.Length) { Sha1Code = ShaHashHelper.GetSHA1(bytes), BlobUrl = url.PrimaryUri.ToString().Split("?")[0] + "/" + name }; return model; } public async Task UploadFile(IFormFile file, string fileSpace = "wordfiles", bool contentTypeDefault = true) { long bizno= IdWorker.getInstance().NextId(); string groupName = fileSpace + "/" + DateTime.Now.ToString("yyyyMMdd")+"/"+ bizno; string newFileName = DateTime.Now.ToString("yyyyMMddHHmmss"); // await InitializeBlob(DateTime.Now.ToString("yyyyMMdd")); blobContainer = blobClient.GetContainerReference(groupName); StorageUri url = blobContainer.StorageUri; string[] names = file.FileName.Split("."); string name = ""; for (int i = 0; i < names.Length - 1; i++) { name = name + names[i]; } if (names.Length <= 1) { name = name + "_" + newFileName; } else { name = name + "_" + newFileName + "." + names[names.Length - 1]; } var parsedContentDisposition = ContentDispositionHeaderValue.Parse(file.ContentDisposition); var filename = Path.Combine(parsedContentDisposition.FileName.Trim('"')); var blockBlob = blobContainer.GetBlockBlobReference(name); string fileext = filename.Substring(filename.LastIndexOf(".") > 0 ? filename.LastIndexOf(".") : 0); if (!contentTypeDefault) { ContentTypeDict.dict.TryGetValue(fileext, out string content_type); if (!string.IsNullOrEmpty(content_type)) { blockBlob.Properties.ContentType = content_type; } } await blockBlob.UploadFromStreamAsync(file.OpenReadStream()); string sha1 = ShaHashHelper.GetSHA1(file.OpenReadStream()); AzureBlobModel model = new AzureBlobModel(file, _options.Container, groupName, name) { Sha1Code=sha1, BlobUrl = url.PrimaryUri.ToString().Split("?")[0] + "/" + name }; return model; } public AzureBlobModel UploadFileByFolderNAsyn(Stream fileSteam, string folder, string fileName, string fileSpace = "pptx", bool contentTypeDefault = true) { string groupName = fileSpace + "/" + folder; // string newFileName = sha1Code; // await InitializeBlob(DateTime.Now.ToString("yyyyMMdd")); blobContainer = blobClient.GetContainerReference(groupName); StorageUri url = blobContainer.StorageUri; string[] names = fileName.Split("."); // string name ; //for (int i = 0; i < names.Length - 1; i++) //{ // name = name + names[i]; //} //if (names.Length <= 1) //{ // name = newFileName; //} //else //{ // name = newFileName + "." + names[names.Length - 1]; //} //var parsedContentDisposition = ContentDispositionHeaderValue.Parse(file.ContentDisposition); //var filename = Path.Combine(parsedContentDisposition.FileName.Trim('"')); var blockBlob = blobContainer.GetBlockBlobReference(fileName); string fileext = fileName.Substring(fileName.LastIndexOf(".") > 0 ? fileName.LastIndexOf(".") : 0); if (!contentTypeDefault) { ContentTypeDict.dict.TryGetValue(fileext, out string content_type); if (!string.IsNullOrEmpty(content_type)) { blockBlob.Properties.ContentType = content_type; } else { blockBlob.Properties.ContentType = "application/octet-stream"; } } blockBlob.UploadFromStreamAsync(fileSteam).GetAwaiter().GetResult() ; AzureBlobModel model = new AzureBlobModel(fileName, _options.Container, groupName, fileName, folder, blockBlob.Properties.ContentType, fileSteam.Length) { Sha1Code = ShaHashHelper.GetSHA1(fileSteam), BlobUrl = url.PrimaryUri.ToString().Split("?")[0] + "/" + fileName }; return model; } public async Task UploadFileByFolder(Stream fileSteam, string folder, string fileName, string fileSpace = "pptx", bool contentTypeDefault = true) { string groupName = fileSpace + "/" + folder; // string newFileName = sha1Code; // await InitializeBlob(DateTime.Now.ToString("yyyyMMdd")); blobContainer = blobClient.GetContainerReference(groupName); StorageUri url = blobContainer.StorageUri; string[] names = fileName.Split("."); // string name ; //for (int i = 0; i < names.Length - 1; i++) //{ // name = name + names[i]; //} //if (names.Length <= 1) //{ // name = newFileName; //} //else //{ // name = newFileName + "." + names[names.Length - 1]; //} //var parsedContentDisposition = ContentDispositionHeaderValue.Parse(file.ContentDisposition); //var filename = Path.Combine(parsedContentDisposition.FileName.Trim('"')); var blockBlob = blobContainer.GetBlockBlobReference(fileName); string fileext = fileName.Substring(fileName.LastIndexOf(".") > 0 ? fileName.LastIndexOf(".") : 0); if (!contentTypeDefault) { ContentTypeDict.dict.TryGetValue(fileext, out string content_type); if (!string.IsNullOrEmpty(content_type)) { blockBlob.Properties.ContentType = content_type; } else { blockBlob.Properties.ContentType = "application/octet-stream"; } } await blockBlob.UploadFromStreamAsync(fileSteam); string sha1 = ShaHashHelper.GetSHA1(fileSteam); AzureBlobModel model = new AzureBlobModel(fileName, _options.Container, groupName, fileName, folder, blockBlob.Properties.ContentType, fileSteam.Length) { Sha1Code = sha1, BlobUrl = url.PrimaryUri.ToString().Split("?")[0] + "/" + fileName }; return model; } public async Task UploadTextByFolder(string text, string folder, string fileName, string fileSpace = "pptx", bool contentTypeDefault = true) { string groupName = fileSpace + "/" + folder; blobContainer = blobClient.GetContainerReference(groupName); StorageUri url = blobContainer.StorageUri; var blockBlob = blobContainer.GetBlockBlobReference(fileName); string fileext = fileName.Substring(fileName.LastIndexOf(".") > 0 ? fileName.LastIndexOf(".") : 0); string content_type = "application/octet-stream"; if (!contentTypeDefault) { ContentTypeDict.dict.TryGetValue(fileext, out string contenttype); if (!string.IsNullOrEmpty(contenttype)) { blockBlob.Properties.ContentType = contenttype; content_type = contenttype; } else { blockBlob.Properties.ContentType = content_type; } } else { blockBlob.Properties.ContentType = content_type; } await blockBlob.UploadTextAsync(text); byte[] bytes = System.Text.Encoding.Default.GetBytes(text); AzureBlobModel model = new AzureBlobModel(fileName, _options.Container, groupName, fileName, folder, blockBlob.Properties.ContentType, bytes.Length) { Sha1Code = ShaHashHelper.GetSHA1(bytes), BlobUrl = url.PrimaryUri.ToString().Split("?")[0] + "/" + fileName }; return model; } /// /// 在容器上创建共享访问策略。 /// /// A reference to the container. /// The name of the stored access policy. public async Task CreateSharedAccessPolicyAsync(string containerName, string policyName) { blobContainer = GetSASBoloClent(containerName); //Create a new shared access policy and define its constraints. SharedAccessBlobPolicy sharedPolicy = new SharedAccessBlobPolicy() { SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(15), Permissions = SharedAccessBlobPermissions.Delete }; //Get the container's existing permissions. BlobContainerPermissions permissions = await blobContainer.GetPermissionsAsync(); if (permissions.SharedAccessPolicies.Count < 5) { //Add the new policy to the container's permissions, and set the container's permissions. permissions.SharedAccessPolicies.TryAdd(policyName, sharedPolicy); await blobContainer.SetPermissionsAsync(permissions); return true; } else return false; } /// /// 删除容器上共享访问策略。 /// /// A reference to the container. /// The name of the stored access policy. public async Task DeleteSharedAccessPolicyAsync(string containerName, string policyName) { blobContainer = GetSASBoloClent(containerName); BlobContainerPermissions permissions = await blobContainer.GetPermissionsAsync(); permissions.SharedAccessPolicies.Remove(policyName); await blobContainer.SetPermissionsAsync(permissions); } /// ///为 blob 容器创建服务 SAS /// 若要为容器创建服务 SAS,请调用 CloudBlobContainer.GetSharedAccessSignature 方法。 ///下面的代码示例在容器上创建 SAS。 如果提供现有存储访问策略的名称,则该策略与 SAS 关联。 如果未提供存储访问策略,则代码会在容器上创建一个临时 SAS。 /// /// /// /// private static string GetContainerSasUri(CloudBlobContainer container, string storedPolicyName = null) { string sasContainerToken; // If no stored policy is specified, create a new access policy and define its constraints. if (storedPolicyName == null) { // Note that the SharedAccessBlobPolicy class is used both to define the parameters of an ad hoc SAS, and // to construct a shared access policy that is saved to the container's shared access policies. SharedAccessBlobPolicy adHocPolicy = new SharedAccessBlobPolicy() { // When the start time for the SAS is omitted, the start time is assumed to be the time when the storage service receives the request. // Omitting the start time for a SAS that is effective immediately helps to avoid clock skew. SharedAccessExpiryTime = DateTime.UtcNow.AddHours(24), Permissions = SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.List }; // Generate the shared access signature on the container, setting the constraints directly on the signature. sasContainerToken = container.GetSharedAccessSignature(adHocPolicy, null); Console.WriteLine("SAS for blob container (ad hoc): {0}", sasContainerToken); Console.WriteLine(); } else { // Generate the shared access signature on the container. In this case, all of the constraints for the // shared access signature are specified on the stored access policy, which is provided by name. // It is also possible to specify some constraints on an ad hoc SAS and others on the stored access policy. sasContainerToken = container.GetSharedAccessSignature(null, storedPolicyName); Console.WriteLine("SAS for blob container (stored access policy): {0}", sasContainerToken); Console.WriteLine(); } // Return the URI string for the container, including the SAS token. return container.Uri + sasContainerToken; } /// /// 若要为 blob 创建服务 SAS,请调用 CloudBlob.GetSharedAccessSignature 方法。 ///下面的代码示例在 blob 上创建 SAS。 如果提供现有存储访问策略的名称,则该策略与 SAS 关联。 如果未提供存储访问策略,则代码会在 Blob 上创建一个临时 SAS。 /// /// /// /// /// public string GetBlobSasUri(string containerName, string blobName, string TEAMModelId, string policyName = null) { string sasBlobToken; blobContainer = GetSASBoloClent(containerName); // Get a reference to a blob within the container. // Note that the blob may not exist yet, but a SAS can still be created for it. CloudBlockBlob blob = blobContainer.GetBlockBlobReference(TEAMModelId + "/" + blobName); if (policyName == null) { // Create a new access policy and define its constraints. // Note that the SharedAccessBlobPolicy class is used both to define the parameters of an ad hoc SAS, and // to construct a shared access policy that is saved to the container's shared access policies. SharedAccessBlobPolicy adHocSAS = new SharedAccessBlobPolicy() { // When the start time for the SAS is omitted, the start time is assumed to be the time when the storage service receives the request. // Omitting the start time for a SAS that is effective immediately helps to avoid clock skew. SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-15), SharedAccessExpiryTime = DateTime.UtcNow.AddHours(2), Permissions = SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.Create }; // Generate the shared access signature on the blob, setting the constraints directly on the signature. sasBlobToken = blob.GetSharedAccessSignature(adHocSAS); } else { // Generate the shared access signature on the blob. In this case, all of the constraints for the // shared access signature are specified on the container's stored access policy. sasBlobToken = blob.GetSharedAccessSignature(null, policyName); } // Return the URI string for the container, including the SAS token. return blob.Uri + sasBlobToken; } private CloudBlobContainer GetSASBoloClent(string containerName) { AzureBlobOptions azureBlobOptions = Configuration.GetSection("Azure:Table").Get(); CloudStorageAccount storageAccount = CloudStorageAccount.Parse(azureBlobOptions.ConnectionString); CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); CloudBlobContainer container = blobClient.GetContainerReference(containerName); return container; } } }