Dosyaları ASP.net'e FileUpload sunucu denetimini kullanmadan karşıya yükleme


99

Eski bir dosya kullanarak göndermek için ASP.net web formu (v3.5) nasıl edinebilirim <input type="file" /> ?

ASP.net FileUpload sunucu denetimini kullanmakla ilgilenmiyorum.

Yanıtlar:


133

Aspx'inizde:

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

Arkasındaki kodda:

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, varyantınızın kullandığı üzücü runat="server", ASP.NET'in sunucu öğelerinden bağımsız değil
Gizli

ya 1'den fazla giriş varsa ve her iki dosya grubu için ayrı işlevlerin gerçekleştirilmesini istiyorsanız.
Neville Nazerane

birden fazla dosya yüklemek için kullanırken, tüm dosyalar için aynı dosya adını döndürür ve bu nedenle ilk dosyayı n sayıda kaydeder. Nasıl aşılacağına dair bir fikrin var mı?
sohaiby

@Martina Birden fazla dosyayı kaydetmek için bu kod parçacığını kontrol edin
sohaiby

1
@DanielJ. Hiçbir olası yolu yoktur değil bir veritabanında depolayarak, yani sonradan dosya ile bir şey yapıyor olması gidiyoruz kod geride kullanın. Elbette, girdi ve dosyayı var fileUploaded = document.getElementById("myFile").files[0];almak için doğrudan JavaScript'i kullanabilirsiniz: ve hatta baytları şu şekilde de alabilirsiniz readAsArrayBuffer: stackoverflow.com/questions/37134433/… - ama tüm bu baytlarla istemci tarafında ne yapacaksınız? OP, ASP .NET kontrolü-sunucu tarafı iletişiminden tamamen kaçınmak ister. -1 size.
vapcguy

40

İşte OP'nin soruda açıkladığı gibi, herhangi bir sunucu tarafı kontrolüne güvenmeden bir çözüm.

İstemci tarafı HTML kodu:

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

Upload.aspx'in Page_Load yöntemi:

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'de tam dosya yolunu gönderen HTTPWebRequest çağrısına dikkat edin. WebClient çağrısı yalnızca dosya adını gönderir. HTTPWebRequest, MyFile.SaveAs'ın başarısız olmasına neden olur. Bir müşterinin çalışıp, bir müşterinin çalışmaması için saatler harcadık.
Bob Clegg

Ben sadece Request.Files[0]yerine kullandım Request.Files["UploadedFile"]ve OP, MVC'yi değil, doğrudan ASP .NET'i kullanırken, bunu MVC için kullanmak isteyen varsa, HttpPostedFileBasebunun yerine ihtiyacınız var HttpPostedFile.
vapcguy

23

İçin enctypeözniteliğini ayarlamanız formgerekir multipart/form-data; daha sonra HttpRequest.Fileskoleksiyonu kullanarak yüklenen dosyaya erişebilirsiniz .


Sunucu formum bir ana sayfadaydı ve multipart / form-data ekleyemedim (o zamandan beri her sayfada olacaktı). Hızlı ve kirli bir çözüm, sayfaya gizli bir FileUpload denetimi eklemekti. WebForms daha sonra çok parçalı / form verilerini otomatik olarak ekledi. Bunu yapmak zorundaydım çünkü Angular2 ile bir dosya girişi kullanıyordum ve bir bileşen şablonunda bir sunucu kontrolü kullanamıyordum.
Jason

9

HTML kontrolünü runat sunucusu niteliği ile kullanma

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

Sonra asp.net Codebehind'de

 FileInput.PostedFile.SaveAs("DestinationPath");

Ayrıca, ilginizi çekerseniz ilerlemeyi gösterecek bazı 3. taraf seçenekleri de vardır.


3
Yine, bu onu bir sunucu kontrolüne dönüştürüyor. ;)
ahwm

@ahwm OP, ASP .NET FileUpload denetiminden ( <asp:FileUpload ID="fileUpload1" runat="server"></asp:FileUpload>) kaçınmak istedi. Bu, runat=serverbir inputalana a koymayın demekten farklıdır .
vapcguy

1
Bunu, ASP.NET denetimlerini kullanmak istemedikleri anlamına gelir. Hangi HtmlInputFilekontrolü içerir .
ahwm

8

Evet, bunu ajax posta yöntemi ile elde edebilirsiniz. sunucu tarafındahtphandler kullanabilirsiniz. Bu nedenle, ihtiyacınıza göre herhangi bir sunucu kontrolü kullanmıyoruz.

ajax ile yükleme ilerlemesini de gösterebilirsiniz.

dosyayı bir girdi akışı olarak okumanız gerekecek.

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

Basit kod

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
Belki de, fs.close()IIS içinde bir şekilde açık kaldıkları için okunamayan dosyalara gidebilecek her şeyi eklemek için ipucu eklemelisiniz .
mistapink

@mistapink Yürütme, using bloğunu terk ettiğinde dosya akışı kapanmıyor mu?
Sebi

@Sebi neredeyse 3 yıl önce olmadı gibi görünüyor. Uzun zamandır denemedim, bu yüzden burada kesin bir cevap veremem. Üzgünüm.
mistapink

4

Request.Files koleksiyonu, bir FileUpload denetiminden veya el ile yazılmış olmasından bağımsız olarak formunuzla yüklenen tüm dosyaları içerir <input type="file">.

Böylece, WebForm'unuzun ortasına düz bir eski dosya giriş etiketi yazabilir ve ardından Request.Files koleksiyonundan yüklenen dosyayı okuyabilirsiniz.


4

Diğerlerinin cevabı olduğu için, Request.Files, gönderilen tüm dosyaları içeren bir HttpFileCollection'dır, yalnızca bu nesneyi dosya için şu şekilde istemeniz gerekir:

Request.Files["myFile"]

Ancak, aynı öznitelik adına sahip birden fazla girdi işaretlemesi olduğunda ne olur:

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

Sunucu tarafında önceki kod Request.Files ["myFile"], iki dosya yerine yalnızca bir HttpPostedFile nesnesi döndürür. .Net 4.5'te GetMultiple adlı bir uzantı yöntemi gördüm, ancak daha önce yapılan sürümler için mevcut değil, bu nedenle uzantı yöntemini şu şekilde öneriyorum:

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

Bu uzantı yöntemi, varsa, HttpFileCollection'da "myFiles" adına sahip tüm HttpPostedFile nesnelerini döndürür.


2

HtmlInputFile denetimi

Bunu her zaman kullandım.


2
Bu, runat="server"onu kullanmak istemedikleri bir sunucu kontrolüne dönüştüren eklemeyi gerektirir .
ahwm

@ahwm Hayır, OP belirli ASP .NET Dosya Yükleme denetimini kullanmak istemedi. Bu, genel olarak bir sunucu tarafı kontrolü kullanmak istemediklerini söylemekten farklıdır.
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();
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.