使用asp.net Identity在Azure Blob存储中更新映像

时间:2017-12-11 16:27:51

标签: asp.net azure asp.net-identity azure-storage-blobs

我目前能够从我的blob存储上传和显示图像,但是如果用户想要更改它,我很难找到“更新/替换”该图像的方法。我对两种方法中的任何一种都很满意:

  1. 替换图片并保持相同的网址
  2. 上传新图片并在数据库中引用新网址
  3. 在控制器中我正在为photoService使用依赖注入:

    管理控制器

    //
        // GET: /Manage/Index
        public async Task<ActionResult> Index(ManageMessageId? message)
        {
            ViewBag.StatusMessage =
                message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
                : message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
                : message == ManageMessageId.SetTwoFactorSuccess ? "Your two-factor authentication provider has been set."
                : message == ManageMessageId.Error ? "An error has occurred."
                : message == ManageMessageId.AddPhoneSuccess ? "Your phone number was added."
                : message == ManageMessageId.RemovePhoneSuccess ? "Your phone number was removed."
                : "";
    
            var userId = User.Identity.GetUserId();
            var model = new IndexViewModel
            {
                HasPassword = HasPassword(),
                PhoneNumber = await UserManager.GetPhoneNumberAsync(userId),
                TwoFactor = await UserManager.GetTwoFactorEnabledAsync(userId),
                Logins = await UserManager.GetLoginsAsync(userId),
                BrowserRemembered = await AuthenticationManager.TwoFactorBrowserRememberedAsync(userId)
            };
    
    
            // PhotoService
            var user = new ApplicationUser
            {
                PhotoUrl = await _photoService.UploadPhotoAsync(model.Photo)
            };
            await UserManager.CreateAsync(user);
            // PhotoService END
    
    
    
            return View(model);
        }
    

    服务

    public class PhotoService : IPhotoService
    {
        public async void CreateAndConfigureAsync()
        {
            try
            {
                CloudStorageAccount storageAccount = StorageUtils.StorageAccount;
    
                // Create a blob client and retrieve reference to images container
                CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
                CloudBlobContainer container = blobClient.GetContainerReference("images");
    
                // Create the "images" container if it doesn't already exist.
                if (await container.CreateIfNotExistsAsync())
                {
                    // Enable public access on the newly created "images" container
                    await container.SetPermissionsAsync(
                        new BlobContainerPermissions
                        {
                            PublicAccess =
                                BlobContainerPublicAccessType.Blob
                        });
    
                    // Logging
                }
            }
            catch (Exception ex)
            {
                // Logging
            }
        }
    
        public async Task<string> UploadPhotoAsync(HttpPostedFileBase photoToUpload)
        {
            if (photoToUpload == null || photoToUpload.ContentLength == 0)
            {
                return null;
            }
    
            string fullPath = null;
            Stopwatch timespan = Stopwatch.StartNew();
    
            try
            {
                CloudStorageAccount storageAccount = StorageUtils.StorageAccount;
    
                // Create the blob client and reference the container
                CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
                CloudBlobContainer container = blobClient.GetContainerReference("images");
    
                // Create a unique name for the images we are about to upload
                string imageName = String.Format("task-photo-{0}{1}",
                    Guid.NewGuid().ToString(),
                    Path.GetExtension(photoToUpload.FileName));
    
                // Upload image to Blob Storage
                CloudBlockBlob blockBlob = container.GetBlockBlobReference(imageName);
                blockBlob.Properties.ContentType = photoToUpload.ContentType;
                await blockBlob.UploadFromStreamAsync(photoToUpload.InputStream);
    
                // Convert to be HTTP based URI (default storage path is HTTPS)
                var uriBuilder = new UriBuilder(blockBlob.Uri);
                uriBuilder.Scheme = "http";
                fullPath = uriBuilder.ToString();
    
                timespan.Stop();
                //log.TraceApi("Blob Service", "PhotoService.UploadPhoto", timespan.Elapsed, "imagepath={0}", fullPath);
            }
            catch (Exception ex)
            {
                //log.Error(ex, "Error upload photo blob to storage");
            }
    
            return fullPath;
        }
    }
    

    接口

    public interface IPhotoService
    {
        void CreateAndConfigureAsync();
        Task<string> UploadPhotoAsync(HttpPostedFileBase photoToUpload);
    }
    

    MODEL

    public class IndexViewModel
    {
        public bool HasPassword { get; set; }
        public IList<UserLoginInfo> Logins { get; set; }
        public string PhoneNumber { get; set; }
        public bool TwoFactor { get; set; }
        public bool BrowserRemembered { get; set; }
        public HttpPostedFileBase Photo { get; set; }
        public string PhotoUrl { get; set; }
    }
    

    查看

    @using Microsoft.AspNet.Identity
    @model AzureBlobStorageTest.Models.IndexViewModel
    @{
    ViewBag.Title = "Manage";
    }
    
    <h2>@ViewBag.Title.</h2>
    
     <p class="text-success">@ViewBag.StatusMessage</p>
     <div>
    <h4>Change your account settings</h4>
    <h5>Image:</h5>
    <img src="@(Model.PhotoUrl)" alt="Photo"/>
    
    
    @using (Html.BeginForm("Index", "Manage", FormMethod.Post, new { role = "form", enctype = "multipart/form-data" }))
    {
        @Html.AntiForgeryToken()
        @Html.ValidationSummary("", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(m => m.Photo, new { @class = "col-md-2 control-label" })
            <div class="col-md-10">
                @Html.TextBoxFor(m => m.Photo, new { type = "file" })
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" class="btn btn-default" value="Register" />
            </div>
        </div>
    }
    </div>
    

    如果有人可以帮我解决这个问题会很好,因为我一直在尝试各种各样的方法,但没有运气。

    如果您需要任何进一步的信息,请与我们联系。

    由于

1 个答案:

答案 0 :(得分:1)

正如Thomas所述,CloudBlockBlob.UploadFromStreamAsync会将流上传到块blob,如果blob已经存在,它将被覆盖。但您的blob名称在UploadPhotoAsync方法下是唯一的,如下所示:

string imageName = String.Format("task-photo-{0}{1}",
            Guid.NewGuid().ToString(),
            Path.GetExtension(photoToUpload.FileName));

我建议您在DeletePhotoAsync下定义一个新方法(例如IPhotoService),然后检索现有图像,然后在调用上传新图像的UploadPhotoAsync方法之前删除它。 / p>

或者您可以为photoUrl方法添加可选参数名称UploadPhotoAsync,如果photoUrl不为空或空,则可以将imageName初始化为如下:

imageName = new CloudBlockBlob(new Uri($"{photoUrl}")).Name;

<强>更新

您的PhotoService看起来像这样:

public class PhotoService:IPhotoService
{
    CloudBlobContainer container;
    public PhotoService()
    {
        CloudStorageAccount storageAccount = StorageUtils.StorageAccount;
        // Create a blob client and retrieve reference to images container
        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
        container= blobClient.GetContainerReference("images");
    }

    //photoUrl: https://<account-name>.blob.core.windows.net/images/task-photo-09e0e292-8df2-4630-81a5-cb4977eef1f9.png
    public async Task<bool> DeletePhotoAsync(string photoUrl)
    {
        string blobName = new CloudBlockBlob(new Uri(photoUrl)).Name;
        var targetBlob = container.GetBlockBlobReference(blobName);
        return await targetBlob.DeleteIfExistsAsync();
    }

    public async void CreateAndConfigureAsync()
    {
      try
      {
        // Create the "images" container if it doesn't already exist.
        if (await container.CreateIfNotExistsAsync())
        {
            // Enable public access on the newly created "images" container
            await container.SetPermissionsAsync(
                new BlobContainerPermissions
                {
                    PublicAccess =
                        BlobContainerPublicAccessType.Blob
                });

            // Logging
        }
     }
     catch (Exception ex)
     {
        // Logging
     }
  }

  //UploadPhotoAsync
}