programing

MVC3에서 Azure Blob 파일 다운로드하기

powerit 2023. 4. 28. 21:44
반응형

MVC3에서 Azure Blob 파일 다운로드하기

저희 ASP.NET MVC 3 애플리케이션은 Azure에서 실행되고 Blob을 파일 스토리지로 사용합니다.업로드 부분을 파악했습니다.

보기에 파일 이름이 표시됩니다. 이 이름을 클릭하면 파일 다운로드 화면이 나타납니다.

이 일을 어떻게 해야 하는지 누가 알려줄 수 있나요?

정말로 두 가지 선택지가...첫 번째는 사용자를 블롭으로 직접 리디렉션하는 것입니다(블롭이 공용 컨테이너에 있는 경우).이는 다음과 같습니다.

return Redirect(container.GetBlobReference(name).Uri.AbsoluteUri);

BLOB가 개인 컨테이너에 있는 경우 Shared Access Signature를 사용하여 이전 예제와 같이 리디렉션하거나 컨트롤러 작업에서 BLOB를 읽고 클라이언트에 다운로드로 푸시할 수 있습니다.

Response.AddHeader("Content-Disposition", "attachment; filename=" + name); // force download
container.GetBlobReference(name).DownloadToStream(Response.OutputStream);
return new EmptyResult();

다음은 개인 BLOB 액세스의 재개 가능한 버전(대용량 파일에 유용하거나 비디오 또는 오디오 재생에서 검색을 허용)입니다.

public class AzureBlobStream : ActionResult
{
    private string filename, containerName;

    public AzureBlobStream(string containerName, string filename)
    {
        this.containerName = containerName;
        this.filename = filename;
        this.contentType = contentType;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        var response = context.HttpContext.Response;
        var request = context.HttpContext.Request;

        var connectionString = ConfigurationManager.ConnectionStrings["Storage"].ConnectionString;
        var account = CloudStorageAccount.Parse(connectionString);
        var client = account.CreateCloudBlobClient();
        var container = client.GetContainerReference(containerName);
        var blob = container.GetBlockBlobReference(filename);

        blob.FetchAttributes();
        var fileLength = blob.Properties.Length;
        var fileExists = fileLength > 0;
        var etag = blob.Properties.ETag;

        var responseLength = fileLength;
        var buffer = new byte[4096];
        var startIndex = 0;

        //if the "If-Match" exists and is different to etag (or is equal to any "*" with no resource) then return 412 precondition failed
        if (request.Headers["If-Match"] == "*" && !fileExists ||
            request.Headers["If-Match"] != null && request.Headers["If-Match"] != "*" && request.Headers["If-Match"] != etag)
        {
            response.StatusCode = (int)HttpStatusCode.PreconditionFailed;
            return;
        }

        if (!fileExists)
        {
            response.StatusCode = (int)HttpStatusCode.NotFound;
            return;
        }

        if (request.Headers["If-None-Match"] == etag)
        {
            response.StatusCode = (int)HttpStatusCode.NotModified;
            return;
        }

        if (request.Headers["Range"] != null && (request.Headers["If-Range"] == null || request.Headers["IF-Range"] == etag))
        {
            var match = Regex.Match(request.Headers["Range"], @"bytes=(\d*)-(\d*)");
            startIndex = Util.Parse<int>(match.Groups[1].Value);
            responseLength = (Util.Parse<int?>(match.Groups[2].Value) + 1 ?? fileLength) - startIndex;
            response.StatusCode = (int)HttpStatusCode.PartialContent;
            response.Headers["Content-Range"] = "bytes " + startIndex + "-" + (startIndex + responseLength - 1) + "/" + fileLength;
        }

        response.Headers["Accept-Ranges"] = "bytes";
        response.Headers["Content-Length"] = responseLength.ToString();
        response.Cache.SetCacheability(HttpCacheability.Public); //required for etag output
        response.Cache.SetETag(etag); //required for IE9 resumable downloads
        response.ContentType = blob.Properties.ContentType;

        blob.DownloadRangeToStream(response.OutputStream, startIndex, responseLength);
    }
}

예:

Response.AddHeader("Content-Disposition", "attachment; filename=" + filename); // force download
return new AzureBlobStream(blobContainerName, filename);

액션 방법에서 응답 스트림에 쓰는 것이 HTTP 헤더를 엉망으로 만든다는 것을 알게 되었습니다.일부 예상 헤더가 누락되었고 다른 헤더가 올바르게 설정되지 않은 헤더도 있습니다.

따라서 응답 스트림에 쓰는 대신 Blob 콘텐츠를 스트림으로 가져와 컨트롤러에 전달합니다.파일() 메서드입니다.

CloudBlockBlob blob = container.GetBlockBlobReference(blobName);
Stream blobStream = blob.OpenRead();
return File(blobStream, blob.Properties.ContentType, "FileName.txt");

언급URL : https://stackoverflow.com/questions/6752000/downloading-azure-blob-files-in-mvc3

반응형