Reputation: 71
I made an Azure Cloud Service, where you can upload and delete files to the cloud storage using Blobs. I wrote sucessfully a method where you can delete the uploaded blobs from the cloud service:
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";
}
}
Here is also the code for View with 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>
Now I want to write a similiar method so you can download each blob from the View. I tried to write the methode using exactly the same code from the delete but instead of
blob.delete();
now
blob.DownloadToFile(File);
This didn't work though. Is there a possibility to change the delete method so it downloads the chosen blob instead of deleting it?
Here is the code of DownloadToFile method:
[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";
}
The name is just the whole filename that is uploaded. Filename is the data path.
The Exception I get is:
UnauthorizedAccessException: The access to the path "C:\Program Files\IIS Express\Eva Passwort.docx" is denied.]
I think that the problem is that my application doesn't have a path to save the file. Is there a possibility to get a dialog where I can chose the path to save?
Upvotes: 7
Views: 65040
Reputation: 7
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);
}
}
}
Upvotes: 1
Reputation: 570
Using Azure Blob Storage SDK v12
new BlobClient(connectionString, containerName, blobName).DownloadTo(pathToDownload);
Upvotes: 2
Reputation: 27793
I want to write a similiar method so you can download each blob from the View.
It seems that you'd like to enable users to download the blob files, the following sample code work fine on my side, please refer to it.
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;
}
}
Note: Detailed information about Controller.File Method.
Upvotes: 10