FileUploadサーバーコントロールを使用せずにASP.netでファイルをアップロードする


99

ASP.net Webフォーム(v3.5)を取得して、プレーンな古いファイルを使用してファイルを投稿するにはどうすればよい<input type="file" />ですか?

ASP.net FileUploadサーバーコントロールの使用には興味がありません。

回答:


133

あなたの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>

後ろのコードで:

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

3
@mathieu、あなたの亜種が使用する同情runat="server"、それはASP.NETのサーバーのものから独立していない
秘密

2つ以上の入力があり、両方のファイルセットで個別の機能を実行したい場合はどうすればよいでしょうか。
Neville Nazerane、2014年

複数のファイルをアップロードするために使用している間、すべてのファイルに対して同じファイル名を返すため、最初のファイルをn回保存します。それを乗り越える方法はありますか?
sohaiby 2015

@Martina 複数のファイルを保存するには、このコードスニペットをチェックしてください
sohaiby

1
@DanielJ。後でファイルに対して何かを行う場合、つまりデータベースに格納する場合に、コードビハインドを使用しない方法はありません。確かに、あなたが入力&ファイルをつかむためにまっすぐにJavaScriptを使用することもできますvar fileUploaded = document.getElementById("myFile").files[0];し、あなたも使ってバイトを取得することができますreadAsArrayBufferstackoverflow.com/questions/37134433/...を -しかし、あなたはすべてのそれらのバイトのクライアント・サイドをどうするつもりですか?OPは、サーバー側の通信ではなくASP .NETコントロールを完全に回避したいと考えています。あなたに-1。
vapcguy

40

OPが質問で説明したように、サーバー側のコントロールに依存しないソリューションは次のとおりです。

クライアント側のHTMLコード:

<form action="upload.aspx" method="post" enctype="multipart/form-data">
    <input type="file" name="UploadedFile" />
</form>

upload.aspxのPage_Loadメソッド:

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

MyFile.FileNameの完全なファイルパスを送信するHTTPWebRequest呼び出しに注意してください。WebClient呼び出しはファイル名を送信するだけです。HTTPWebRequestにより、MyFile.SaveAsが失敗します。1つのクライアントが機能していて、1つのクライアントが機能していないことを追いかけて、時間を無駄にしただけです。
Bob Clegg 2016年

私はちょうど使用Request.Files[0]の代わりRequest.Files["UploadedFile"]とOPはあなただけ必要な、誰もがMVCのためにこれを使用したい場合は、MVCストレートASP .NETを使用していなかった間、HttpPostedFileBase代わりにHttpPostedFile
vapcguy

23

あなたは、設定する必要がありますenctypeの属性formにしますmultipart/form-data。その後、HttpRequest.Filesコレクションを使用してアップロードしたファイルにアクセスできます。


サーバーフォームがマスターページにあり、multipart / form-dataを追加できませんでした(それ以降はすべてのページにあるため)。簡単で汚い回避策は、非表示のFileUploadコントロールをページに追加することでした。WebFormsはmultipart / form-dataを自動的に追加しました。Angular2でファイル入力を使用していて、コンポーネントテンプレートでサーバーコントロールを使用できなかったため、これを行う必要がありました。
Jason

9

runatサーバー属性でHTMLコントロールを使用する

 <input id="FileInput" runat="server" type="file" />

その後、asp.net Codebehind

 FileInput.PostedFile.SaveAs("DestinationPath");

また、あなたが参加した場合に進捗状況を示すいくつかのサードパーティのオプションもあります


3
繰り返しになりますが、サーバーコントロールに変わります。;)
ahwm

@ahwm OPは、ASP .NETのFileUploadコントロール(<asp:FileUpload ID="fileUpload1" runat="server"></asp:FileUpload>)を回避したいと考えていrunat=serverましたinput
vapcguy

1
私は、ASP.NETコントロールを使用したくないことを意味します。これにはHtmlInputFileコントロールが含まれます。
ahwm

8

はい、これはajax postメソッドで実現できます。サーバー側ではhttphandlerを使用できます。したがって、要件に応じてサーバーコントロールを使用していません。

ajaxを使用すると、アップロードの進行状況も表示できます。

入力ストリームとしてファイルを読み取る必要があります。

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

サンプルコード

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

2
fs.close()IIS内で何らかの理由で開いたままなので、ヒントを追加して、他のすべてが読み取り不能なファイルになる可能性があるすべてを追加する必要があるかもしれません。
mistapink

@mistapink実行がusingブロックを離れたときにファイルストリームが閉じていませんか?
セビ

@Sebiほぼ3年前のようです。長い間やってみなかったので、ここでは明確な答えは出せません。ごめんなさい。
mistapink

4

Request.Filesコレクションには、FileUploadコントロールからのものか、手動で記述されたものかに関係なく、フォームでアップロードされたファイルが含まれ<input type="file">ます。

そのため、WebFormの途中でプレーンな古いファイル入力タグを記述し、Request.Filesコレクションからアップロードされたファイルを読み取ることができます。


4

他の人が答えているように、Request.Filesは投稿されたすべてのファイルを含むHttpFileCollectionであり、次のようにそのオブジェクトにファイルを要求するだけで済みます。

Request.Files["myFile"]

ただし、同じ属性名を持つ複数の入力マークアップがある場合はどうなりますか。

Select file 1 <input type="file" name="myFiles" />
Select file 2 <input type="file" name="myFiles" />

サーバー側では、前のコードRequest.Files ["myFile"]は、2つのファイルではなく1つのHttpPostedFileオブジェクトのみを返します。私は.net 4.5でGetMultipleと呼ばれる拡張メソッドを見てきましたが、貴重なバージョンでは存在しません。そのため、拡張メソッドを次のように提案します。

public static IEnumerable<HttpPostedFile> GetMultiple(this HttpFileCollection pCollection, string pName)
{
        for (int i = 0; i < pCollection.Count; i++)
        {
            if (pCollection.GetKey(i).Equals(pName))
            {
                yield return pCollection.Get(i);
            }
        }
}

この拡張メソッドは、存在する場合、HttpFileCollectionに「myFiles」という名前のすべてのHttpPostedFileオブジェクトを返します。


2

HtmlInputFileコントロール

私はいつもこれを使いました。


2
それには、runat="server"基本的にそれをサーバーコントロールに変える追加が必要ですが、使用したくありませんでした。
ahwm 2013

@ahwmいいえ、OPは特定のASP .NET FileUploadコントロールを使用したくありませんでした。これは、一般的にサーバー側のコントロールを使用したくないと言っているのとは異なります。
vapcguy


0
//create a folder in server (~/Uploads)
 //to upload
 File.Copy(@"D:\CORREO.txt", Server.MapPath("~/Uploads/CORREO.txt"));

 //to download
             Response.ContentType = ContentType;
             Response.AppendHeader("Content-Disposition", "attachment;filename=" + Path.GetFileName("~/Uploads/CORREO.txt"));
             Response.WriteFile("~/Uploads/CORREO.txt");
             Response.End();
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.