Comment télécharger de gros fichiers à l'Azure blob à partir d'une page web
En interne ASP.NET a un 2 GO d'espace d'adressage, mais en réalité, vous avez pas plus de 1 GO gratuit pour les téléchargements (voir http://support.microsoft.com/?id=295626 ). En outre IIS 7 a un plafond de 30 MO ( voir http://www.iislogs.com/steveschofield/iis7-post-40-adjusting-file-upload-size-in-iis7 ) et vous avez soi-disant pour exécuter
appcmd set config "My Site/MyApp" -section:requestFiltering -requestLimits.maxAllowedContentLength:104857600 -commitpath:apphost
sur le serveur pour aller au-delà de cette limite de 30 MO. Mais comment puis-je exécuter sur mes serveurs Azure?
Aussi, selon http://support.microsoft.com/?id=295626
Pendant le processus de téléchargement, ASP.NET
les charges de l'ensemble du fichier en mémoire avant
l'utilisateur peut enregistrer le fichier à l'
de disque.
donc je vais épuiser rapidement la limite de la mémoire si de nombreux utilisateurs de télécharger de gros fichiers à la fois. Dans mon code ci-dessous j'ai utiliser les flux, mais je devine que tout le fichier est téléchargé dans la mémoire de toute façon. Est-ce le cas?
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();
}
}
}
}
Je suis conscient de la non page web de téléchargement des outils comme http://azureblobuploader.codeplex.com/ , mais j'ai vraiment besoin d'être téléchargés à partir d'une page web.
Donc, mes questions sont les suivantes:
- Comment puis-je télécharger des fichiers sur le blob qui sont plus de 2 GO à partir d'une page web
- Comment puis-je grand de télécharger des fichiers à partir d'une page web comme un flux qui ne mangent pas tous la mémoire
- Si la solution est d'écrire ma propre HttpModule ou HttpHandler pour gérer mon upload, comment puis-je obtenir de l'installer sur mon Azure serveurs? Puis-je utiliser HttpHandlers comme http://neatupload.codeplex.com/ sur Azure?
- Ce projet n'est pas sur SharePoint, mais je sait que dans SharePoint vous avez quelque chose qui s'appelle une Goutte Fournisseur et que vous pouvez écrire votre propre, il y a Blob Fournisseurs pour ASP.NET?
Je peux aussi mentionner que mon code ci-dessus fonctionne très bien par défaut avec des fichiers de moins de 30 MO, j'utilise SWFUpload V2.2.0 sur le client.
Mise à jour 19. Juin 19:09:
@YvesGoeleven sur Twitter m'a donné une astuce de l'utilisation de la Signature d'Accès Partagé (voir msdn.microsoft.com/en-us/library/ee395415.aspx ) et d'envoyer le fichier directement à l'Azure Blob Storage, sans passer par le ASP.NET à tous. J'ai créé un JSON WCF qui renvoie valide SAS ut à mon blob storage.
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);
}
}
}
Il fonctionne, mais je ne peux pas l'utiliser avec SWFUpload car il utilise le HTTP verbe POST et de ne pas le METTRE HTTP verbe que l'Azure Blob Storage attend lors de la création d'un nouveau blob élément. Quelqu'un sait comment contourner ce problème sans faire mon propre Silverlight ou Flash composant client qui utilise le HTTP PUT verbe? Je voulais une barre de progression lors du téléchargement de fichiers, donc de la soumission d'un formulaire qui utilise n'est pas optimale.
Pour ceux qui sont intéressés dans le code du client (qui ne fonctionnent pas depuis SWFUpload utilise HTTP POST et ne pas METTRE comme Azure Blob Storage attend):
<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>
Mise à jour 19. Juin 21:07:
J'ai trouvé depuis SWFUpload est open source que j'ai télécharger la source et changer le verbe de POST pour METTRE, malheureusement, le Flash Player URLRequestMethod ne prend pas en charge d'autres verbes que GET et POST. J'ai trouvé un supposé travailler autour de
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"));
mais cela n'a de travail dans Adobe Air et pas avec le Flash Player.
J'ai lu que SilverLight 3 et versions ultérieures prennent en charge le HTTP PUT verbe, donc je pense que je dois écrire quelques SilverLight code pour obtenir mon chemin. J'ai trouvé cet article de blog de la série qui va probablement m'aider ici http://blog.smarx.com/posts/uploading-windows-azure-blobs-from-silverlight-part-1-shared-access-signatures .
Mise à jour @ 27. Juin '11:
J'ai maintenant réussi à télécharger de gros fichiers (testé avec 4,5 Go de fichiers) à partir d'une page web à l'aide d'un custom client Silverlight, j'ai écrit basé sur le projet dans http://blog.smarx.com/posts/uploading-windows-azure-blobs-from-silverlight-part-1-shared-access-signatures . Depuis Silverlight prend en charge le HTTP PUT verbe qui Azure Blob Storage nécessite et prend en charge progressive téléchargements, j'ai maintenant la possibilité de télécharger massive des fichiers directement à l'Azure Blob Storage et je n'ai pas à aller throgh un ASP.NET la solution, je reçois aussi quelques belles barres de progression, et l'utilisateur peut annuler dans le milieu de la télécharger si il/elle veut. L'utilisation de la mémoire sur le serveur est minime puisque le fichier n'est pas téléchargé, avant d'être placé dans l'Azure Blob Storage. J'utilise une Signature d'Accès Partagé (voir msdn.microsoft.com/en-us/library/ee395415.aspx ) qui est alimenté à partir d'un WCF de Détente sur demande. Je pense que cette solution est la meilleure que nous ayons trouvé. Merci.
Mise à jour @ 18. Juillet '11:
J'ai créé un projet open source avec ce que j'ai trouvé ici:
http://azureslfileuploader.codeplex.com/
OriginalL'auteur | 2011-06-19
Vous devez vous connecter pour publier un commentaire.
J'ai fait exactement la même chose récemment. J'ai créé un Client Silverlight application pour gérer de découper les données et de les envoyer sur Azure.
Cette est un exemple de travail que j'ai suivi qui fait exactement cela. Assez bien suivre ce et vous êtes travail est presque bien fait pour vous.
OriginalL'auteur Gabe
n'importe quel modèle de code que vous utilisez. Si vous écrivez un code côté serveur, puis fichier, aller à votre webrole puis plusieurs douleurs telles que le rôle de recycler et de la nouvelle tentative a échoué uploads va venir. J'ai enlevé ces questions si un contrôle Silverlight, qui n'a pas seulement à tolérance de pannes téléchargements, mais aussi il l'a fait à grande vitesse. Vous pouvez télécharger mon échantillon et de lire comment je l'ai construit à partir de: Choisissez Votre Azure Fichier de Contrôle de Téléchargement: Silverlight et TPL ou HTML5, AJAX
OriginalL'auteur Rahul
On peut télécharger des fichiers très volumineux dans le stockage azure en utilisant en parallèle de téléchargement.
Cela signifie que nous avons besoin de diviser de gros fichiers en pièces de petit fichier de paquets et de
et uoploaded ces paquets. Une fois le téléchargement terminé, nous pouvons rejoindre les paquets de
un exemplaire original.
Pour le code complet veuillez consulter le lien suivant
http://tuvian.wordpress.com/2011/06/28/how-to-upload-large-size-fileblob-to-azure-storage-using-asp-netc/
OriginalL'auteur tuvian
Pour cette partie de la question:
Vous pouvez le faire à l'aide de tâches de démarrage - voir http://richardprodger.wordpress.com/2011/03/22/azure-iis7-configuration-with-appcmd/
OriginalL'auteur Stuart