11

内部的には、ASP.NETには2 GBのアドレス空間がありますが、実際には、アップロードに使用できる空き容量は1 GB未満です(http://support.microsoft.com/?id=295626を参照)。さらに、IIS7の上限は30MBであり(http://www.iislogs.com/steveschofield/iis7-post-40-adjusting-file-upload-size-in-iis7を参照)、おそらく実行する必要があります。

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

サーバー上でこの30MBの制限を超えます。しかし、Azureサーバーでこれを実行するにはどうすればよいですか?

また、http://support.microsoft.com/?id=295626によると

アップロードプロセス中に、ASP.NETは、ユーザーがファイルをディスクに保存する前に、ファイル全体をメモリにロードします。

、したがって、多くのユーザーが一度に大きなファイルをアップロードすると、メモリ制限をすぐに使い果たしてしまいます。以下のコードではストリームを使用していますが、とにかくファイル全体が最初にメモリにアップロードされると思います。これは本当ですか?

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();
            }
        }
    }
}

http://azureblobuploader.codeplex.com/のようなWebページ以外のアップロードツールを知っていますが、実際にはWebページからアップロードする必要があります。

だから、私の質問は次のとおりです。

  1. Webページから2GBを超えるファイルをblobにアップロードする方法
  2. すべてのメモリを消費しないストリームとしてWebページからファイルを大きくアップロードするにはどうすればよいですか?
  3. 解決策がアップロードを処理するために独自のHttpModuleまたはHttpHandlerを作成することである場合、これをAzureサーバーにインストールするにはどうすればよいですか?Azureでhttp://neatupload.codeplex.com/のようなHttpHandlerを使用できますか?
  4. このプロジェクトはSharePoint上にありませんが、SharePointにはBlobプロバイダーと呼ばれるものがあり、独自に作成できることを知っています。ASP.NET用のBlobプロバイダーはありますか?

上記のコードは、デフォルトで30 MB未満のファイルで正常に機能することにも言及できます。クライアントでは、SWFUploadV2.2.0を使用しています。

更新19.6月19:09: Twitterの@YvesGoelevenから、共有アクセス署名(msdn.microsoft.com/en-us/library/ee395415.aspxを参照)を使用し、ファイルをAzureBlobStorageに直接アップロードする方法を教えてもらいました。 ASP.NETをまったく通過しません。有効なSASutをblobストレージに返すJSONWCFを作成しました。

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);
        }
    }
}

動作しますが、新しいblobアイテムを作成するときにAzure BlobStorageが期待するHTTPPUT動詞ではなく、HTTP POST動詞を使用するため、SWFUploadでは使用できません。HTTP PUT動詞を使用する独自のカスタムSilverlightまたはFlashクライアントコンポーネントを作成せずにこれを回避する方法を知っている人はいますか?ファイルをアップロードするときにプログレスバーが必要だったため、PUTを使用して送信されたフォームは最適ではありません。

クライアントコードに関心のある方(SWFUploadはHTTP POSTを使用し、Azure Blob Storageが期待するPUTではないため機能しません):

    <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>

更新19.6月21:07:

SWFUploadはオープンソースであるため、ソースをダウンロードして動詞をPOSTからPUTに変更すると思いました。残念ながら、FlashPlayerURLRequestMethodはGETとPOST以外の動詞をサポートしていません。想定される回避策を見つけました

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"));

、ただし、これはAdobe Airでのみ機能し、FlashPlayerでは機能しません。

SilverLight3以降がHTTPPUT動詞をサポートしていることを読んだので、ここにたどり着くには、SilverLightコードを作成する必要があると思います。おそらくここhttp://blog.smarx.com/posts/uploading-windows-azure-blobs-from-silverlight-part-1-shared-access-signaturesで役立つこのブログ記事シリーズを見つけました。

更新@27。2011年6月:

これで、 http://blog.smarx.com/posts/uploading-windows-のプロジェクトに基づいて作成したカスタムSilverlightクライアントを使用して、Webページから大きなファイル(4,5 Gbファイルでテスト済み)を正常にアップロードできました。azure-blobs-from-silverlight-part-1-shared-access-signatures。Silverlightは、Azure BlobStorageが必要とするHTTPPUT動詞とプログレスアップロードの両方をサポートしているため、大量のファイルをAzure Blob Storageに直接アップロードできるようになり、ASP.NETソリューションを使用する必要もありません。いくつかの素晴らしいプログレスバーを取得し、ユーザーは必要に応じてアップロードの途中でキャンセルできます。ファイル全体がAzureBlobStorageに配置される前にアップロードされないため、サーバーのメモリ使用量は最小限に抑えられます。要求に応じてWCFRESTfullサービスから提供される共有アクセス署名(msdn.microsoft.com/en-us/library/ee395415.aspxを参照)を使用します。この解決策は私たちが見つけた最高のものだと思います。ありがとう。

更新@18。2011年7月:

ここで見つけたものを使用してオープンソースプロジェクトを作成しました。

http://azureslfileuploader.codeplex.com/

4

4 に答える 4

3

使用するコードパターンに関係なく。サーバー側のコードを作成すると、ファイルはWebロールに送られ、ロールのリサイクルや失敗したアップロードの再試行など、いくつかの問題が発生します。クライアント側のSilverlightコントロールを使用してこれらの問題を削除しました。これにより、フォールトトレラントなアップロードが行われただけでなく、非常に高速にアップロードされました。サンプルをダウンロードして、その作成方法を読むことができます。Azureファイルのアップロードコントロールを選択する:SilverlightとTPL、またはHTML5とAJAX

于 2011-11-01T18:30:12.947 に答える
3

私は実際に最近まったく同じことをしました。データを切り刻んでAzureに送信するためのSilverlightクライアントアプリを作成しました。

これは私が従った実際の例であり、まさにそれを実行します。ほぼこれに従ってください、そしてあなたの仕事はほとんどあなたのために行われます。

于 2011-06-27T21:37:29.007 に答える
2

並列アップロードを使用して、非常に大きなファイルをAzureストレージにアップロードできます。つまり、大きなファイルを小さなファイルパケットに分割し、これらのパケットをuoploadする必要があります。アップロードが完了すると、パケットを元のパケットに結合できます。完全なコードについては、次のリンクを参照してください http://tuvian.wordpress.com/2011/06/28/how-to-upload-large-size-fileblob-to-azure-storage-using-asp-netc/

于 2011-06-28T13:54:40.947 に答える
-1

質問のこの部分について:

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

サーバー上でこの30MBの制限を超えます。しかし、Azureサーバーでこれを実行するにはどうすればよいですか?

これは、起動タスクを使用して行うことができます-http://richardprodger.wordpress.com/2011/03/22/azure-iis7-configuration-with-appcmd/を参照してください

于 2011-06-20T11:02:20.987 に答える