2011-08-11 26 views

Trả lời

32

Cho phép người dùng tải xuống tệp (blobs) trong Windows Azure có thể được thực hiện theo 4 cách;

  • Direct Tải - Tập hợp dữ liệu của các container để đọc công cộng Access hoặc Full Công đọc truy cập và phơi bày URL cho người dùng cuối. Hạn chế của phương pháp này rõ ràng là bảo mật - bạn không có cách nào kiểm soát quyền truy cập khi URL được hiển thị. Cũng không có cách nào để phát hiện tải xuống và thực thi mã trước/sau khi tải xuống.

  • API Tải xuống - Người dùng phải chạy ứng dụng Windows, Silverlight, v.v. - ứng dụng phải chứa tên và khóa mã hóa - có thể làm tổn hại đến bảo mật. Đặc biệt là nếu bạn có một số khách hàng sử dụng cùng một tài khoản (họ vẫn có thể có thùng chứa riêng của họ tất nhiên).

  • Proxy Tải xuống - Yêu cầu người dùng truy cập URL trên máy chủ CỦA BẠN - sau đó truy xuất tệp từ Azure và gửi tệp đó cho người dùng. Lợi thế của việc này là bạn có toàn quyền kiểm soát tải xuống, bạn có thể thực thi mã trước/sau khi tải xuống và bạn không phải hiển thị bất kỳ thông tin tài khoản/URL của Azure nào. Trong thực tế - người dùng cuối thậm chí sẽ không thấy rằng tệp được lưu trữ trong Azure. Bạn cũng có thể ghi đè tên tập tin theo cách này. Nhược điểm là tất cả lưu lượng truy cập đi qua máy chủ của bạn - vì vậy, bạn có thể nhận được một nút cổ chai ở đây.

  • Tải xuống qua (Chữ ký truy cập chia sẻ Azure) - Tạo chữ ký và chèn chữ ký này vào URL nơi người dùng được chuyển hướng đến Azure. Chữ ký cho phép người dùng truy cập tệp trong một khoảng thời gian giới hạn. Đây có thể là lựa chọn tốt nhất của bạn. Nó cho phép mã tùy chỉnh được thực hiện trước khi tải xuống, nó sẽ đảm bảo tốc độ tải xuống tối đa cho người dùng của bạn và mức độ bảo mật tốt cũng được đảm bảo.

Đây là đoạn mã sẽ truyền tệp tới người dùng và ghi đè tên tệp.

//Retrieve filenname from DB (based on fileid (Guid)) 
// *SNIP* 
string filename = "some file name.txt"; 

//IE needs URL encoded filename. Important when there are spaces and other non-ansi chars in filename. 
if (HttpContext.Current.Request.UserAgent != null &&  HttpContext.Current.Request.UserAgent.ToUpper().Contains("MSIE")) 
filename = HttpUtility.UrlEncode(filename, System.Text.Encoding.UTF8).Replace("+", " "); 

context.Response.Charset = "UTF-8"; 
//Important to set buffer to false. IIS will download entire blob before passing it on to user if this is not set to false 
context.Response.Buffer = false; 
context.Response.AddHeader("Content-Disposition", "attachment; filename=\"" + filename + "\""); 
context.Response.AddHeader("Content-Length", "100122334"); //Set the length the file 
context.Response.ContentType = "application/octet-stream"; 
context.Response.Flush(); 

//Use the Azure API to stream the blob to the user instantly. 
// *SNIP* 
fileBlob.DownloadToStream(context.Response.OutputStream); 

Xem bài đăng trên blog này để biết thêm: http://blog.degree.no/2012/04/downloading-blobs-from-windows-azure/

+0

Cảm ơn bạn đã trả lời rất chi tiết này. Tải xuống thông qua âm thanh chính xác những gì tôi cần. Một câu hỏi, trong ví dụ mã của bạn, bạn đặt kích thước của tệp, điều này có phải được thực hiện vì tôi không biết thông tin này mà không truy cập tệp. – CeejeeB

+0

Không cần thiết đặt tệp. Tôi làm điều đó để cho phép người dùng (trình duyệt) xem tiến trình tải xuống. Nếu bạn không đặt, trình duyệt sẽ hiển thị "không xác định tệp", v.v. khi tải xuống. –

+0

Trong tùy chọn 3 - tải tập tin đầu tiên vào thư mục localresource (tạm thời) của webrole và sau đó liên kết url đó với người dùng cuối. điều này có thể không? ý tưởng tốt? Trong tùy chọn 4 là có một cách để ẩn url SAS từ người dùng cuối và làm cho họ chỉ cần lưu các tập tin. Tất cả các tệp tôi đang xử lý ở đây là xml. – Aravind

0

Thứ nhất, bạn có thể sử dụng tên miền riêng của bạn cho blob URI: http://blogs.msdn.com/b/avkashchauhan/archive/2011/03/22/using-custom-domain-name-with-windows-azure-storage-instead-of-windows-stroage-name-blob-core-windows-net.aspx

dụ của giải pháp cho bạn ...

using Microsoft.WindowsAzure; 
using Microsoft.WindowsAzure.StorageClient; 

StorageCredentialsAccountAndKey credentials = new StorageCredentialsAccountAndKey(ConfigurationManager.AppSettings["WindowsAzureStorageAccountName"], ConfigurationManager.AppSettings["WindowsAzureStorageAccountKey"]); 
CloudStorageAccount cloudStorageAccount = new CloudStorageAccount(credentials, true); 

CloudBlobContainer blobContainer = blobClient.GetContainerReference("mycontainer"); 

// e.g. GUID of currently logged in user 
string fileName = System.Web.Security.Membership.GetUser().ProviderUserKey.ToString(); 

CloudBlob blob = blobContainer.GetBlobReference(fileName); 

byte[] blobArray = blob.DownloadByteArray(); 

Response.ContentType = "text/plain"; 
Response.AddHeader("content-disposition", "attachment; filename=" + "MyText.txt"); 
Response.BinaryWrite(blobArray); 
Response.End(); 
+1

tôi thấy những gì bạn đang nói nhưng điều đó phụ thuộc tôi tải tệp xuống máy chủ của tôi trước khi chuyển nó lên máy khách. Tôi cần cho khách hàng để có thể tải trực tiếp từ máy chủ Azure. – CeejeeB

+0

Bạn cần một số loại viết lại URL dựa trên GUID người dùng. Có lẽ điều này có thể giúp: http://forums.asp.net/t/1574817.aspx/1 –

4

Câu trả lời là không. Bạn sẽ cần phải đặt tiêu đề bố trí nội dung trên blob và không có cách nào để đặt tiêu đề đó trong bộ nhớ blob.

+0

Cảm ơn bạn. Tôi nghĩ vậy nhưng chỉ muốn chắc chắn. – CeejeeB

+6

Ngoài những cách giải quyết khác được đề xuất, nếu bạn luôn muốn có cùng một tên thân thiện, bạn có thể chỉ cần đặt tên những thứ như 'http://me.blob.core.windows.net/mycontainer/9BB34783-8F06-466D-AC20-37A03E504E3F/ MyText.txt' – smarx

+2

Cảm ơn @smarx - đây là một giải pháp thực sự đơn giản và thanh lịch – dmichael

13

Tính đến tháng 11 năm 2013 bây giờ có hỗ trợ cho tiêu đề nội dung bố trí trong Windows Azure Blob lưu trữ. Bạn có thể gán tiêu đề hoặc tạo blob hoặc thông qua chữ ký truy cập dùng chung.

Tôi đã sửa đổi phương pháp lưu tài liệu của mình để lấy tham số tùy chọn là tên thân thiện để tải xuống.

public void SaveDocument(Stream documentToSave, string contentType, string containerName, string url, string friendlyName = null) 
{ 
    var container = GetContainer(containerName); 
    container.CreateIfNotExists(); 
    var blob = container.GetBlockBlobReference(url); 
    blob.Properties.ContentType = contentType; 
    if (friendlyName != null) 
     blob.Properties.ContentDisposition = "attachment; filename=" + friendlyName; 
    blob.UploadFromStream(documentToSave); 
} 

Thông tin thêm về nó: http://blog.simontimms.com/2013/12/02/content-disposition-comes-to-azure/

+0

Cảm ơn bạn đã cập nhật này – CeejeeB

33

Bây giờ có thể bằng cách thiết lập các tiêu đề nội dung bố trí vào việc tạo chữ ký Chia sẻ kết nối:

string sasBlobToken = blob.GetSharedAccessSignature(sharedPolicy, new SharedAccessBlobHeaders() 
      { 
       ContentDisposition = "attachment; filename=" + friendlyFileName 
      }); 
    string downloadLink = blob.Uri + sasBlobToken; 
+3

Genius, chính xác những gì tôi đang tìm kiếm! – Bern

+0

P L U S O N E. Chỉ cần những gì tôi cần –

Các vấn đề liên quan