2011-06-19 26 views
11

ASP.NET nội bộ có dung lượng địa chỉ 2 GB, nhưng trên thực tế bạn chỉ có ít hơn 1 GB miễn phí để tải lên (xem http://support.microsoft.com/?id=295626). Ngoài IIS 7 có một chiếc mũ của 30 MB (xem http://www.iislogs.com/steveschofield/iis7-post-40-adjusting-file-upload-size-in-iis7) và bạn được cho là phải chạyCách tải tệp lớn lên đốm màu Azure từ trang web

appcmd set config "My Site/MyApp" -section:requestFiltering -requestLimits.maxAllowedContentLength:104857600 -commitpath:apphost 

trên máy chủ để vượt qua giới hạn 30 MB này. Nhưng làm thế nào tôi có thể chạy trên máy chủ Azure của tôi?

Ngoài ra, theo http://support.microsoft.com/?id=295626

Trong quá trình upload, ASP.NET tải toàn bộ tập tin trong bộ nhớ trước khi người dùng có thể lưu các tập tin vào đĩa .

, vì vậy tôi sẽ nhanh chóng cạn kiệt giới hạn bộ nhớ nếu nhiều người dùng tải lên các tệp lớn cùng một lúc. Trong mã của tôi dưới đây tôi sử dụng dòng, nhưng tôi đoán rằng toàn bộ tập tin được tải lên trong bộ nhớ đầu tiên anyway. Đây có phải là trường hợp không?

using System; 
using System.Web.Security; 
using Microsoft.WindowsAzure; 
using Microsoft.WindowsAzure.StorageClient; 

namespace WebPages 
{ 
    public partial class Upload : System.Web.UI.Page 
    { 
     CloudBlobClient BlobClient = null; 
     CloudBlobContainer BlobContainer = null; 

     void InitBlob() 
     { 
      // Setup the connection to Windows Azure Storage 
      var storageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString"); 
      BlobClient = storageAccount.CreateCloudBlobClient(); 

      // Get and create the container 
      BlobContainer = BlobClient.GetContainerReference("publicfiles"); 
     } 

     protected void Page_Load(object sender, EventArgs e) 
     { 
      //if (Membership.GetUser() == null) return; // Only allow registered users to upload files 

      InitBlob(); 

      try 
      { 
       var file = Request.Files["Filedata"]; 

       var storageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString"); 
       BlobClient = storageAccount.CreateCloudBlobClient(); 

       // Make a unique blob name 
       var extension = System.IO.Path.GetExtension(file.FileName); 

       // Create the Blob and upload the file 
       var blobAddressUri = String.Format("{0}{1}", Guid.NewGuid(), extension); 
       var blob = BlobContainer.GetBlobReference(blobAddressUri); 

       blob.UploadFromStream(file.InputStream); 

       // Set the metadata into the blob 
       blob.Metadata["FileName"] = file.FileName; 
       //blob.Metadata["Submitter"] = Membership.GetUser().UserName; 
       blob.Metadata["Type"] = "Video"; 
       blob.Metadata["Description"] = "Test"; 
       blob.SetMetadata(); 

       // Set the properties 
       blob.Properties.ContentType = file.ContentType; 
       blob.SetProperties(); 
      } 
      catch(Exception ex) 
      { 
       System.Diagnostics.Trace.TraceError("Upload file exception: {0}", ex.ToString()); 
       // If any kind of error occurs return a 500 Internal Server error 
       Response.StatusCode = 500; 
       Response.Write("An error occured while uploading the file"); 
       Response.End(); 
      } 
     } 
    } 
} 

Tôi biết các công cụ tải lên trang web không như http://azureblobuploader.codeplex.com/, nhưng tôi thực sự cần nó để được tải lên từ một trang web.

Vì vậy, câu hỏi của tôi là:

  1. Làm thế nào để tôi tải lên tập tin vào blob có dung lượng lớn hơn 2 GB từ một trang web
  2. Làm thế nào để tải lên tập tin lớn từ một trang web như một dòng suối mà không ăn tất cả bộ nhớ
  3. Nếu giải pháp là viết HttpModule hoặc HttpHandler của riêng tôi để xử lý tải lên của tôi, làm cách nào tôi có thể cài đặt này trên máy chủ Azure của mình? Tôi có thể sử dụng HttpHandlers như http://neatupload.codeplex.com/ trên Azure không?
  4. Dự án này không có trong SharePoint, nhưng tôi hiểu rằng trong SharePoint bạn có một cái gì đó được gọi là Nhà cung cấp Blob và bạn có thể tự viết, có Nhà cung cấp Blob cho ASP.NET không?

Tôi cũng có thể đề cập rằng mã của tôi ở trên hoạt động tốt theo mặc định với các tệp nhỏ hơn 30 MB, tôi sử dụng SWFUpload V2.2.0 trên máy khách.

Cập nhật 19. Tháng Sáu 19:09: @YvesGoeleven trên Twitter đã cho tôi một lời khuyên của việc sử dụng Chia sẻ kết nối Chữ ký (xem msdn.microsoft.com/en-us/library/ee395415.aspx) và tải lên các tập tin trực tiếp đến bộ lưu trữ Azure Blob mà không phải trải qua ASP.NET chút nào. Tôi tạo ra một WCF JSON trả về một SAS ut hợp lệ để lưu trữ blob của tôi.

using System.ServiceModel; 
using System.ServiceModel.Web; 

namespace WebPages.Interfaces 
{ 
    [ServiceContract] 
    public interface IUpload 
    { 
     [OperationContract] 
     [WebInvoke(Method = "GET", 
      ResponseFormat = WebMessageFormat.Json)] 
     string GetUploadUrl(); 
    } 
} 

-------- 

using System; 
using System.IO; 
using System.Runtime.Serialization.Json; 
using System.ServiceModel.Activation; 
using System.Text; 
using Microsoft.WindowsAzure; 
using Microsoft.WindowsAzure.StorageClient; 

namespace WebPages.Interfaces 
{ 
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 
    public class UploadService : IUpload 
    { 
     CloudBlobClient BlobClient; 
     CloudBlobContainer BlobContainer; 

     public UploadService() 
     { 
      // Setup the connection to Windows Azure Storage 
      var storageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString"); 
      BlobClient = storageAccount.CreateCloudBlobClient(); 

      // Get and create the container 
      BlobContainer = BlobClient.GetContainerReference("publicfiles"); 
     } 

     string JsonSerialize(string url) 
     { 
      var serializer = new DataContractJsonSerializer(url.GetType()); 
      var memoryStream = new MemoryStream(); 

      serializer.WriteObject(memoryStream, url); 

      return Encoding.Default.GetString(memoryStream.ToArray()); 
     } 

     public string GetUploadUrl() 
     { 
      var sasWithIdentifier = BlobContainer.GetSharedAccessSignature(new SharedAccessPolicy() 
      { 
       Permissions = SharedAccessPermissions.Write, 
       SharedAccessExpiryTime = 
        DateTime.UtcNow.AddMinutes(60) 
      }); 
      return JsonSerialize(BlobContainer.Uri.AbsoluteUri + "/" + Guid.NewGuid() + sasWithIdentifier); 
     } 
    } 
} 

Nó hoạt động, nhưng tôi không thể sử dụng nó với SWFUpload vì nó sử dụng động từ HTTP POST và không phải là động từ HTTP PUT mà Azure Blob Storage mong đợi khi tạo một mục blob mới. Bất cứ ai cũng biết làm thế nào để có được điều này mà không cần tạo thành phần Silverlight hoặc Flash client tùy chỉnh của riêng tôi sử dụng động từ HTTP PUT? Tôi muốn một thanh tiến trình khi tải lên các tệp, do đó biểu mẫu đã gửi sử dụng PUT không phải là tối ưu.

Đối với những người quan tâm đến mã khách hàng (rằng công việc sẽ không từ SWFUpload sử dụng HTTP POST và không PUT như Azure Blob lưu trữ dự kiến):

<div id="header"> 
     <h1 id="logo"><a href="/">SWFUpload</a></h1> 
     <div id="version">v2.2.0</div> 
    </div> 
    <div id="content"> 
     <h2>Application Demo (ASP.Net 2.0)</h2> 
     <div id="swfu_container" style="margin: 0px 10px;"> 
      <div> 
       <span id="spanButtonPlaceholder"></span> 
      </div> 
      <div id="divFileProgressContainer" style="height: 75px;"></div> 
      <div id="thumbnails"></div> 
     </div> 
    </div> 

<script type="text/javascript" language="javascript"> 
     $(document).ready(function() { 

      $.ajax({ 
       url: '/Interfaces/UploadService.svc/GetUploadUrl', 
       success: function (result) { 
        var parsedResult = $.parseJSON(result); 
        InitUploadFile(parsedResult); 
       } 
      }); 


      function InitUploadFile(uploadUrl) { 
       //alert(uploadUrl); 
       var swfu = new SWFUpload({ 
        // Backend Settings 
        upload_url: uploadUrl, 
        post_params: { 
         "ASPSESSID": "<%=Session.SessionID %>" 
        }, 

        // File Upload Settings 
        file_size_limit: "100 MB", 
        file_types: "*.*", 
        file_types_description: "All file types", 
        file_upload_limit: "0", // Zero means unlimited 

        // Event Handler Settings - these functions as defined in Handlers.js 
        // The handlers are not part of SWFUpload but are part of my website and control how 
        // my website reacts to the SWFUpload events. 
        file_queue_error_handler: fileQueueError, 
        file_dialog_complete_handler: fileDialogComplete, 
        upload_progress_handler: uploadProgress, 
        upload_error_handler: uploadError, 
        upload_success_handler: uploadSuccess, 
        upload_complete_handler: uploadComplete, 

        // Button settings 
        button_image_url: "Images/swfupload/XPButtonNoText_160x22.png", 
        button_placeholder_id: "spanButtonPlaceholder", 
        button_width: 160, 
        button_height: 22, 
        button_text: '<span class="button">Select files <span class="buttonSmall">(2 MB Max)</span></span>', 
        button_text_style: '.button { font-family: Helvetica, Arial, sans-serif; font-size: 14pt; } .buttonSmall { font-size: 10pt; }', 
        button_text_top_padding: 1, 
        button_text_left_padding: 5, 

        // Flash Settings 
        flash_url: "Js/swfupload-2.2.0/swfupload.swf", // Relative to this file 

        custom_settings: { 
         upload_target: "divFileProgressContainer" 
        }, 

        // Debug Settings 
        debug: false 
       }); 
      } 
     }); 
    </script> 

Cập nhật 19. Tháng Sáu 21:07:

Tôi đã tìm ra vì SWFUpload là mã nguồn mở mà tôi tải xuống nguồn và thay đổi động từ POST thành PUT, đáng buồn là FlashRequestMethod không hỗ trợ các động từ khác so với GET và POST. Tôi đã tìm thấy một tác phẩm giả định xung quanh

private function BuildRequest():URLRequest { 
    // Create the request object 
    var request:URLRequest = new URLRequest(); 
    request.method = URLRequestMethod.POST; 
    request.requestHeaders.push(new URLRequestHeader("X-HTTP-Method-Override", "PUT")); 

, nhưng điều này chỉ hoạt động trong Adobe Air chứ không phải với Trình phát Flash.

Tôi đã đọc rằng SilverLight 3 và sau đó hỗ trợ động từ HTTP PUT, vì vậy tôi nghĩ tôi phải viết một số mã SilverLight để tìm đường đến đây. Tôi đã tìm thấy loạt bài viết trên blog này có thể sẽ giúp tôi ở đây http://blog.smarx.com/posts/uploading-windows-azure-blobs-from-silverlight-part-1-shared-access-signatures.

Cập nhật @ 27. Tháng Sáu '11:

bây giờ tôi đã thành công trong việc upload file lớn (thử nghiệm với 4,5 Gb file) từ một trang web bằng cách sử dụng Silverlight client tùy chỉnh tôi đã viết dựa trên dự án tại http://blog.smarx.com/posts/uploading-windows-azure-blobs-from-silverlight-part-1-shared-access-signatures. Vì Silverlight hỗ trợ cả động từ HTTP PUT mà Azure Blob Storage yêu cầu và hỗ trợ tải lên lũy tiến, bây giờ tôi có khả năng tải các tệp lớn trực tiếp lên Bộ nhớ Azure Blob và tôi không phải đi giải pháp ASP.NET, tôi cũng có được một số thanh tiến trình tốt đẹp và người dùng có thể hủy ở giữa quá trình tải lên nếu anh ta/cô ấy muốn. Việc sử dụng bộ nhớ trên máy chủ là tối thiểu kể từ khi toàn bộ tập tin không được tải lên trước khi nó được đặt trong bộ nhớ Azure Blob. Tôi sử dụng một Signature Access Signature (xem msdn.microsoft.com/en-us/library/ee395415.aspx) được cung cấp từ một dịch vụ WCF RESTfull theo yêu cầu. Tôi nghĩ rằng giải pháp này là giải pháp tốt nhất mà chúng tôi tìm thấy. Cảm ơn.

Cập nhật @ 18. Tháng Bảy '11:

Tôi đã tạo ra một dự án mã nguồn mở với những gì tôi tìm thấy ở đây:

http://azureslfileuploader.codeplex.com/

Trả lời

3

Tôi thực sự đã làm điều tương tự gần đây. Tôi đã tạo một ứng dụng Silverlight Client để xử lý việc cắt xén dữ liệu và gửi nó tới Azure.

This là ví dụ hoạt động mà tôi theo dõi thực hiện chính xác điều đó. Khá nhiều làm theo này và bạn đang làm việc gần như được thực hiện nhiều cho bạn.

-1

Đối với phần này của câu hỏi:

appcmd set config "My Site/MyApp" -section:requestFiltering -requestLimits.maxAllowedContentLength:104857600 -commitpath:apphost 

trên máy chủ để vượt quá điều này 30 Giới hạn MB. Nhưng làm thế nào tôi có thể chạy trên máy chủ Azure của tôi?

Bạn có thể làm điều này bằng việc khởi động - xem http://richardprodger.wordpress.com/2011/03/22/azure-iis7-configuration-with-appcmd/

2

Chúng tôi có thể tải lên các tệp rất lớn vào bộ nhớ xanh bằng cách sử dụng tải lên song song. Điều đó có nghĩa là chúng ta cần phải chia nhỏ các tệp lớn thành các tệp gói nhỏ và và uoploaded các gói này.Khi quá trình tải lên hoàn tất, chúng tôi có thể tham gia các gói với số một gói gốc. Để có mã hoàn chỉnh, vui lòng tham khảo liên kết sau http://tuvian.wordpress.com/2011/06/28/how-to-upload-large-size-fileblob-to-azure-storage-using-asp-netc/

3

cho dù bạn sử dụng mẫu mã nào. Nếu bạn viết một mã phía máy chủ, sau đó tập tin sẽ đi đến webrole của bạn và sau đó một số cơn đau như vai trò tái chế và thử lại tải lên không thành công sẽ đến. Tôi đã loại bỏ những vấn đề này mặc dù điều khiển Silverlight của phía khách hàng, điều đó không chỉ làm cho tải lên có khả năng chịu lỗi mà còn ở tốc độ tuyệt vời. Bạn có thể tải xuống mẫu của tôi và đọc cách tôi tạo mẫu từ: Pick Your Azure File Upload Control: Silverlight and TPL or HTML5 and AJAX

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