如何将图片存储在 asp.net mvc 应用程序的 azure blob 存储中?

Posted

技术标签:

【中文标题】如何将图片存储在 asp.net mvc 应用程序的 azure blob 存储中?【英文标题】:How do I store a picture in azure blob storage in asp.net mvc application? 【发布时间】:2020-06-22 07:47:57 【问题描述】:

我目前正在开发一个存储学生信息的 ASP.Net 应用程序。我需要存储以下信息:

学号 姓名 电子邮件地址 家庭住址 联系电话 上传学生照片 isActive 标志表明学生是否活跃

此信息存储在文档数据库中,学生的照片需要上传到 Azure blob 存储,同时将图像链接返回到文档数据库

我该怎么做?

我目前有一个学生信息类,如下所示:

public class Student

    [Key]
    public int StudentId  get; set; 

    [Required]
    [StringLength(8, MinimumLength = 8)]
    [DisplayName("Student Number")]
    public string StudentNo  get; set; 

    [Required]
    [StringLength(50, MinimumLength = 1)]
    [DisplayName("First Name")]
    public string FirstName  get; set; 

    [Required]
    [StringLength(50, MinimumLength = 1)]
    [DisplayName("Last Name")]
    public string LastName  get; set; 

    [Required]
    [DataType(DataType.EmailAddress)]
    [DisplayName("Email Address")]
    public string Email  get; set; 

    [Required]
    [StringLength(100, MinimumLength = 5)]
    [DataType(DataType.MultilineText)]
    [DisplayName("Home Address")]
    public string HomeAddress  get; set; 

    [Required]
    [DataType(DataType.PhoneNumber)]
    [StringLength(10)]
    [DisplayName("Mobile No.")]
    public string Mobile  get; set; 

    public bool IsActive  get; set; 

我有一个单独的 blob 视图模型,因为我仍在尝试使用 blob:

 public class BlobViewModel


    public string BlobContainerName  get; set; 
    public string StorageUri  get; set; 
    public string ActualFileName  get; set; 
    public string PrimaryUri  get; set; 
    public string fileExtension  get; set; 

    public string FileNameWithoutExt
    
        get
        
            return Path.GetFileNameWithoutExtension(ActualFileName);
        
    

    public string FileNameExtensionOnly
    
        get
        
            return System.IO.Path.GetExtension(ActualFileName).Substring(1);
        
    

如何将这两者结合起来,以便在将 URI 返回给学生类的同时上传学生的图像以存储在 blob 中?

【问题讨论】:

请编辑您的问题,包括您迄今为止尝试过的内容以及您遇到的问题。 我建议查看this related question(和答案)以获得一些想法。至于如何上传你的内容?这完全取决于您 - 没有单一的方法可以做到这一点。但是...在上传您需要存储为 blob 的任何内容后,将该 blob 的 URI 捕获到文档架构中的一个属性(或 set 属性)中。 【参考方案1】:

首先,您需要从 azure 门户创建 azure 存储帐户和容器。然后您可以创建如下方法。您可以将文件保存在 azure blob 存储中唯一文件名的文件夹下,并将文件名存储在您的 SQL 数据库。可以通过传递目标文件夹信息和唯一文件名来访问保存的文件。

Updload File:

    public static void UploadBlob(string targetfolder, string fileName, FileStream fileStream)
    
        try
        
            if (!string.IsNullOrWhiteSpace(fileName) && fileStream != null)
            
                string storageConnection = CloudConfigurationManager.GetSetting("your storage connection string");
                CloudStorageAccount StorageAccount = CloudStorageAccount.Parse(storageConnection);
                CloudBlobClient BlobClient = StorageAccount.CreateCloudBlobClient();
                CloudBlobContainer cloudBlobContainer = BlobClient.GetContainerReference("your container name");

                CloudBlockBlob blockBlob = cloudBlobContainer.GetBlockBlobReference(targetFolder + fileName);

                blockBlob.UploadFromStream(fileStream);
            
        
        catch (Exception ex)
        
            throw new Exception("File Upload Failed");
        
    

Download File:

    public ActionResult DownloadFile()
        

            Stream stream =DownloadFilelob(targetFolder,fileName)
            return File(stream, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
        


public Stream DownloadFileBlob(string targetFolder, string fileName)

    try
    
        if (!string.IsNullOrWhiteSpace(fileName))
        
            string storageConnection = CloudConfigurationManager.GetSetting("your storage connection string");
            CloudStorageAccount StorageAccount = CloudStorageAccount.Parse(storageConnection);
            CloudBlobClient BlobClient = StorageAccount.CreateCloudBlobClient();
            CloudBlobContainer cloudBlobContainer = BlobClient.GetContainerReference("your container name");

            CloudBlockBlob blockBlob = cloudBlobContainer.GetBlockBlobReference(targetFolder + fileName);

    return blockBlob.OpenRead()
        
    
    catch (Exception ex)
    
        throw new Exception("File Download Failed");
    

【讨论】:

【参考方案2】:

使用 Azure CosmosDB 作为存储可能会有所帮助。 使用 CosmosDB,您可以轻松地将图像存储为学生文档的附件:https://docs.microsoft.com/en-us/rest/api/cosmos-db/attachments

如果您不打算使用 CosmosDB,请更准确地了解数据库存储。

【讨论】:

我不建议将 Cosmos DB 附件作为推荐的解决方案。除了要求所有访问权限都通过 Cosmos DB 本身(例如,直接链接到 Azure 存储)之外,还有 2GB 的容量限制。 你是对的。顺便说一句,如果您有中等数量的学生并为每张上传的照片设置大小限制,则 2GB 存储所有照片就足够了, 不要使用附件在 Cosmos DB 中存储 blob。将 Blob 存储在 Azure Blob 存储中,并将资源的 URI 存储在 Cosmos DB 中。 谢谢你,马克,为这个讨论。非常令人兴奋。我的第一个答案不是很好,或者我错了。当我谈论使用附件时,我建议将 Azure 存储中资源的 URI 引用存储为 Cosmos DB 中的附件。这是否与 Azure Cosmos DB 上的文档一致? 是的,正确的设计是存储 blob 的元数据,包括它在 Cosmos DB 中的 URI。谢谢。

以上是关于如何将图片存储在 asp.net mvc 应用程序的 azure blob 存储中?的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET MVC 4 - 上传图片到数据库

使用 Asp.Net MVC 创建私人照片库

如何将类的对象发送到数据库以存储在 ASP.NET MVC5 中?

如何在 ASP.NET Core MVC 中使用依赖注入设计存储库模式?

在 Asp.Net MVC 应用程序中使用 Structuremap 将 ISession 注入我的存储库

如何从 ASP.NET MVC 视图显示存储在数据库中的 HTML?