如何使用下载链接从Azure Blob Storage下载文件

7

我创建了一个Azure云服务,在其中可以使用Blob上传和删除文件到云存储。我成功编写了一个方法,可以从云服务中删除已上传的Blob:

 public string DeleteImage(string Name)
    {
        Uri uri = new Uri(Name);
        string filename = System.IO.Path.GetFileName(uri.LocalPath);

        CloudBlobContainer blobContainer = _blobStorageService.GetCloudBlobContainer();
        CloudBlockBlob blob = blobContainer.GetBlockBlobReference(filename);

        blob.Delete();

        return "File Deleted";
    }
}

这里也是使用HTML的视图代码:

@{
ViewBag.Title = "Upload";
}

<h2>Upload Image</h2>

<p>
@using (Html.BeginForm("Upload", "Home", FormMethod.Post, new { enctype = 
"multipart/form-data" }))
{
    <input type="file" name="image"/>
    <input type="submit" value="upload" />
}

</p>

<ul style="list-style-position:Outside;padding:0;">
@foreach (var item in Model)
{
<li>
    <img src="@item" alt="image here" width="100" height="100" />
    <a id="@item" href="#" onclick="deleteImage ('@item');">Delete</a>

</li>
}
</ul>

<script>
function deleteImage(item) {
    var url = "/Home/DeleteImage";
    $.post(url, { Name: item }, function (data){
        window.location.href = "/Home/Upload";
    });
}

</script> 

现在我想写一个类似的方法,这样你就可以从视图中下载每个blob。我试着使用与删除完全相同的代码来编写该方法,但是不是使用


blob.delete();

现在

blob.DownloadToFile(File);

然而,这并没有奏效。是否有可能更改删除方法,以便它下载所选的 blob 而不是删除它?


添加信息

以下是 DownloadToFile 方法的代码:

[HttpPost]
    public string DownloadImage(string Name)
    {
        Uri uri = new Uri(Name);
        string filename = System.IO.Path.GetFileName(uri.LocalPath);

        CloudBlobContainer blobContainer = 
_blobStorageService.GetCloudBlobContainer();
        CloudBlockBlob blob = blobContainer.GetBlockBlobReference(filename);

        blob.DownloadToFile(filename, System.IO.FileMode.Create);


        return "File Downloaded";
    }

名称只是上传的完整文件名。文件名是数据路径。

我得到的异常是:

UnauthorizedAccessException:拒绝访问路径"C:\Program Files\IIS Express\Eva Passwort.docx"。

我认为问题在于我的应用程序没有保存文件的路径。有可能获得一个对话框,在其中选择要保存的路径吗?


你能分享一下你的 DownloadToFile 代码吗?并且说明一下你遇到了什么错误。 - Venkata Dorisala
请分享一些关于“名称”和“文件名”的例子,同时提供您遇到的异常详细信息,否则我们无法提供帮助。 - Zhaoxing Lu
我在下面发布了DownloadToFile方法。 - Minh Anh Le Quoc
3个回答

9

我想写一个类似的方法,让你可以从视图中下载每个 Blob。

看起来你想让用户能够下载 Blob 文件,下面的示例代码在我的端上运行良好,请参考它。

public ActionResult DownloadImage()
{
    try
    {
        var filename = "xxx.PNG";
        var storageAccount = CloudStorageAccount.Parse("{connection_string}");
        var blobClient = storageAccount.CreateCloudBlobClient();

        CloudBlobContainer container = blobClient.GetContainerReference("mycontainer");
        CloudBlockBlob blob = container.GetBlockBlobReference(filename);

        Stream blobStream = blob.OpenRead();

        return File(blobStream, blob.Properties.ContentType, filename);

    }
    catch (Exception)
    {
        //download failed 
        //handle exception
        throw;
    }
}

注意: 关于 Controller.File 方法 的详细信息。


7
是否可以通过URL直接下载文件内容?基本上我的前端不是基于MVC的,因此我无法创建一个ActionResult。我只想要一个简单的下载URL,并且如果需要的话,可以在HTTP请求中传递身份验证令牌/密钥。 - Souvik Ghosh
是的,有一种方法可以使用共享访问策略和标头生成预签名URL(一次性链接)。https://medium.com/@harshavardhan.ghorpade/cloud-agnostic-upload-download-apis-using-pre-signed-urls-aws-azure-google-cloud-b99c59ac819d - ShellNinja

2

这正是我所需要的,它运行得非常好。 - J_L

1
using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.File;
using OC3.Core.Model.Server;

namespace OC3.API.Controllers
{
    [Route("v1/desktop/[controller]")]
    [ApiController]
    [EnableCors("AllowOrigin")]
    public class DownloadController : Controller
    {
        private readonly IConfiguration _configuration;

        public DownloadController(IConfiguration configuration)
        {
            _configuration = configuration;
        }

        // code added by Ameer for downloading the attachment from shipments
        [HttpGet("Attachment")]
        public async Task<ActionResult> ActionResultAsync(string filepath)
        {
            ResponseMessage responseMessage = new ResponseMessage();

            responseMessage.resultType = "Download";

            try
            {
                if (!string.IsNullOrEmpty(filepath))
                {
                    responseMessage.totalCount = 1;

                    
                    string shareName = string.Empty;        

                    filepath = filepath.Replace("\\", "/");
                    string fileName = filepath.Split("//").Last();
                    if (filepath.Contains("//"))
                    {
                        //Gets the Folder path of the file.
                        shareName = filepath.Substring(0, filepath.LastIndexOf("//")).Replace("//", "/"); 
                    }
                    else
                    {
                        responseMessage.result = "File Path is null/incorrect";
                        return Ok(responseMessage);
                    }

                    string storageAccount_connectionString = _configuration["Download:StorageConnectionString"].ToString();
                    // get file share root reference
                    CloudFileClient client = CloudStorageAccount.Parse(storageAccount_connectionString).CreateCloudFileClient();
                    CloudFileShare share = client.GetShareReference(shareName);

                    // pass the file name here with extension
                    CloudFile cloudFile = share.GetRootDirectoryReference().GetFileReference(fileName);


                    var memoryStream = new MemoryStream();
                    await cloudFile.DownloadToStreamAsync(memoryStream);
                    responseMessage.result = "Success";

                    var contentType = "application/octet-stream";

                    using (var stream = new MemoryStream())
                    {
                        return File(memoryStream.GetBuffer(), contentType, fileName);
                    }
                }
                else
                {
                    responseMessage.result = "File Path is null/incorrect";
                }
            }
            catch (HttpRequestException ex)
            {
                if (ex.Message.Contains(StatusCodes.Status400BadRequest.ToString(CultureInfo.CurrentCulture)))
                {
                    responseMessage.result = ex.Message;
                    return StatusCode(StatusCodes.Status400BadRequest);
                }
            }
            catch (Exception ex)
            {
                // if file folder path or file is not available the exception will be caught here
                responseMessage.result = ex.Message;
                return Ok(responseMessage);
            }

            return Ok(responseMessage);
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接