Comment puis-je faire en sorte qu'un formulaire Web ASP.net (v3.5) affiche un fichier à l'aide d'un simple formulaire de type <input type="file" />
?
Je ne souhaite pas utiliser le contrôle de serveur FileUpload d'ASP.net.
Comment puis-je faire en sorte qu'un formulaire Web ASP.net (v3.5) affiche un fichier à l'aide d'un simple formulaire de type <input type="file" />
?
Je ne souhaite pas utiliser le contrôle de serveur FileUpload d'ASP.net.
Dans votre aspx :
<form id="form1" runat="server" enctype="multipart/form-data">
<input type="file" id="myFile" name="myFile" />
<asp:Button runat="server" ID="btnUpload" OnClick="btnUploadClick" Text="Upload" />
</form>
Dans le code derrière :
protected void btnUploadClick(object sender, EventArgs e)
{
HttpPostedFile file = Request.Files["myFile"];
//check file was submitted
if (file != null && file.ContentLength > 0)
{
string fname = Path.GetFileName(file.FileName);
file.SaveAs(Server.MapPath(Path.Combine("~/App_Data/", fname)));
}
}
@mathieu, dommage que votre variante utilise runat="server"
il n'est pas indépendant de la partie serveur d'ASP.NET.
Que faire s'il y a plus d'une entrée et que vous voulez que des fonctions distinctes soient exécutées avec les deux ensembles de fichiers.
En l'utilisant pour télécharger plusieurs fichiers, il renvoie le même nom de fichier pour tous les fichiers et enregistre donc le premier fichier n nombre de fois. Avez-vous une idée de la façon de surmonter ce problème ?
Voici une solution qui ne repose sur aucun contrôle côté serveur, comme le décrit le PO dans sa question.
Code HTML côté client :
<form action="upload.aspx" method="post" enctype="multipart/form-data">
<input type="file" name="UploadedFile" />
</form>
Méthode Page_Load de upload.aspx :
if(Request.Files["UploadedFile"] != null)
{
HttpPostedFile MyFile = Request.Files["UploadedFile"];
//Setting location to upload files
string TargetLocation = Server.MapPath("~/Files/");
try
{
if (MyFile.ContentLength > 0)
{
//Determining file name. You can format it as you wish.
string FileName = MyFile.FileName;
//Determining file size.
int FileSize = MyFile.ContentLength;
//Creating a byte array corresponding to file size.
byte[] FileByteArray = new byte[FileSize];
//Posted file is being pushed into byte array.
MyFile.InputStream.Read(FileByteArray, 0, FileSize);
//Uploading properly formatted file to server.
MyFile.SaveAs(TargetLocation + FileName);
}
}
catch(Exception BlueScreen)
{
//Handle errors
}
}
Attention à l'appel HTTPWebRequest qui envoie le chemin complet du fichier dans MyFile.FileName. L'appel WebClient n'envoie que le nom du fichier. L'appel HTTPWebRequest entraînera l'échec de MyFile.SaveAs. J'ai perdu des heures à chercher un client qui fonctionne et un autre qui ne fonctionne pas.
Le formulaire de mon serveur se trouvait sur une page principale et je ne pouvais pas ajouter le format multipart/form-data (car il serait alors présent sur toutes les pages). Une solution de contournement rapide a été d'ajouter un contrôle FileUpload caché à la page. WebForms a alors ajouté automatiquement les données multipart/form-data. J'ai dû procéder ainsi parce que j'utilisais une entrée de fichier avec Angular2 et que je ne pouvais pas utiliser un contrôle de serveur dans un modèle de composant.
Utiliser le contrôle HTML avec un attribut de serveur runat
<input id="FileInput" runat="server" type="file" />
Puis dans asp.net Codebehind
FileInput.PostedFile.SaveAs("DestinationPath");
Il y a aussi des 3ème partie des options qui montrent les progrès réalisés si vous êtes intéressés
@ahwm L'OP voulait éviter le contrôle ASP.NET FileUpload ( <asp:FileUpload ID="fileUpload1" runat="server"></asp:FileUpload>
) C'est différent que de dire de ne pas mettre un runat=server
sur un input
champ.
Oui, vous pouvez réaliser ceci par la méthode ajax post. Du côté du serveur, vous pouvez utiliser httphandler. Donc, nous n'utilisons pas de contrôles de serveur comme vous l'avez demandé.
avec ajax vous pouvez aussi montrer la progression du téléchargement.
vous devrez lire le fichier comme un flux d'entrée.
using (FileStream fs = File.Create("D:\\_Workarea\\" + fileName))
{
Byte[] buffer = new Byte[32 * 1024];
int read = context.Request.GetBufferlessInputStream().Read(buffer, 0, buffer.Length);
while (read > 0)
{
fs.Write(buffer, 0, read);
read = context.Request.GetBufferlessInputStream().Read(buffer, 0, buffer.Length);
}
}
Exemple de code
function sendFile(file) {
debugger;
$.ajax({
url: 'handler/FileUploader.ashx?FileName=' + file.name, //server script to process data
type: 'POST',
xhr: function () {
myXhr = $.ajaxSettings.xhr();
if (myXhr.upload) {
myXhr.upload.addEventListener('progress', progressHandlingFunction, false);
}
return myXhr;
},
success: function (result) {
//On success if you want to perform some tasks.
},
data: file,
cache: false,
contentType: false,
processData: false
});
function progressHandlingFunction(e) {
if (e.lengthComputable) {
var s = parseInt((e.loaded / e.total) * 100);
$("#progress" + currFile).text(s + "%");
$("#progbarWidth" + currFile).width(s + "%");
if (s == 100) {
triggerNextFileUpload();
}
}
}
}
Vous devriez peut-être ajouter l'indication d'ajouter un fs.close()
tout le reste pourrait se retrouver dans des fichiers illisibles puisqu'ils restent en quelque sorte ouverts dans IIS.
@mistapink Le flux de fichiers n'est-il pas fermé lorsque l'exécution quitte le bloc using ?
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.