gpt4 book ai didi

asp.net - 如何从网页将大文件上传到 Azure blob

转载 作者:行者123 更新时间:2023-12-02 03:09:30 26 4
gpt4 key购买 nike

ASP.NET 内部有 2 GB 的寻址空间,但实际上您只有不到 1 GB 的可用空间可供上传(参见 http://support.microsoft.com/?id=295626)。此外,IIS 7 的上限为 30 MB(请参阅 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

在服务器上超出此 30 MB 限制。但是我怎样才能在我的 Azure 服务器上运行它呢?

此外,根据 http://support.microsoft.com/?id=295626

During the upload process, ASP.NET loads the whole file in memory before the user can save the file to the disk.



,所以如果很多用户一次上传大文件,我会很快耗尽内存限制。在我下面的代码中,我使用了流,但我猜无论如何首先将整个文件上传到内存中。是这种情况吗?
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/ ,但我真的需要它从网页上传。

所以,我的问题是:
  • 如何将大于 2 GB 的文件从网页上传到 blob
  • 如何将网页中的大文件上传为不占用所有内存的流
  • 如果解决方案是编写我自己的 HttpModule 或 HttpHandler 来处理我的上传,我该如何在我的 Azure 服务器上安装它?我可以使用像 http://neatupload.codeplex.com/ 这样的 HttpHandlers 吗?在 Azure 上?
  • 这个项目不在 SharePoint 上,但我知道在 SharePoint 中你有一个叫做 Blob Provider 的东西,你可以自己编写,是否有用于 ASP.NET 的 Blob Providers?

  • 我还可以提到,我上面的代码在默认情况下可以很好地处理小于 30 MB 的文件,我在客户端上使用 SWFUpload V2.2.0。

    6 月 19 日 19:09 更新:
    Twitter 上的 @YvesGoeleven 给了我使用共享访问签名的提示(请参阅 msdn.microsoft.com/en-us/library/ee395415.aspx)并将文件直接上传到 Azure Blob 存储,而根本不通过 ASP.NET .我创建了一个 JSON WCF,它将一个有效的 SAS ut 返回到我的 blob 存储。
    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);
    }
    }
    }

    它可以工作,但我不能将它与 SWFUpload 一起使用,因为它使用 HTTP POST 动词,而不是 Azure Blob 存储在创建新 Blob 项时期望的 HTTP PUT 动词。任何人都知道如何在不制作我自己的使用 HTTP PUT 动词的自定义 Silverlight 或 Flash 客户端组件的情况下解决这个问题?我在上传文件时想要一个进度条,因此使用 PUT 的提交表单不是最佳选择。

    对于那些对客户端代码感兴趣的人(因为 SWFUpload 使用 HTTP POST 而不是像 Azure Blob 存储所期望的那样 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>

    6 月 19 日 21:07 更新:

    我想因为 SWFUpload 是开源的,所以我下载了源代码并将动词从 POST 更改为 PUT,遗憾的是 Flash Player URLRequestMethod 不支持除 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"));

    ,但这仅适用于 Adob​​e Air,不适用于 Flash Player。

    我已经读过 SilverLight 3 和更高版本支持 HTTP PUT 动词,所以我想我必须编写一些 SilverLight 代码才能达到我的目的。我确实找到了这个博客文章系列,它可能会对我有所帮助 http://blog.smarx.com/posts/uploading-windows-azure-blobs-from-silverlight-part-1-shared-access-signatures .

    11 年 6 月 27 日更新:

    我现在已经成功地使用我根据 http://blog.smarx.com/posts/uploading-windows-azure-blobs-from-silverlight-part-1-shared-access-signatures 中的项目编写的自定义 Silverlight 客户端从网页上传大文件(使用 4,5 Gb 文件测试)。 .由于 Silverlight 既支持 Azure Blob 存储所需的 HTTP PUT 动词,又支持渐进式上传,因此我现在可以将大量文件直接上传到 Azure Blob 存储,而不必通过 ASP.NET 解决方案,我也获得一些不错的进度条,如果他/她愿意,用户可以在上传过程中取消。服务器上的内存使用量很小,因为在将整个文件放入 Azure Blob 存储之前不会上传整个文件。我使用 WCF RESTfull 服务应要求提供的共享访问签名(请参阅 msdn.microsoft.com/en-us/library/ee395415.aspx)。我认为这个解决方案是我们找到的最好的解决方案。谢谢。

    11 年 7 月 18 日更新:

    我用我在这里找到的东西创建了一个开源项目:

    http://azureslfileuploader.codeplex.com/

    最佳答案

    实际上,我最近做了完全相同的事情。我创建了一个 Silverlight 客户端应用程序来处理切碎数据并将其发送到 Azure。

    This是我遵循的一个工作示例,它正是这样做的。几乎遵循这一点,你的工作几乎已经为你完成了。

    关于asp.net - 如何从网页将大文件上传到 Azure blob,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6402253/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com