99

How can I get an ASP.net web form (v3.5) to post a file using a plain old <input type="file" />?

I am not interested in using the ASP.net FileUpload server control.

0

9 Answers 9

134

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

In code behind :

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)));
    }
}
Sign up to request clarification or add additional context in comments.

7 Comments

@mathieu, pity that you variant does use runat="server", it isn't independent from the server stuff of ASP.NET
what if there are more than 1 inputs and you want separate functions performed with both sets of files.
while using it to upload multiple files, it returns same file name for all files and hence save the first file n number of times. Any idea how to get over it?
@Martina Check this code snippet for saving multiple files
@DanielJ. There is no possible way to not use code-behind if you're going to be doing anything with the file afterwards, i.e. storing it in a database. Sure, you could use straight JavaScript to grab the input & file: var fileUploaded = document.getElementById("myFile").files[0]; and you can even get the bytes using readAsArrayBuffer: stackoverflow.com/questions/37134433/… - but what are you going to do with all those bytes client-side? The OP wants to avoid the ASP .NET control-not server-side communication altogether. -1 to you.
|
41

Here is a solution without relying on any server-side control, just like OP has described in the question.

Client side HTML code:

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

Page_Load method of 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
    }
}

2 Comments

Watch out for HTTPWebRequest call sending full file path in MyFile.FileName. WebClient call just sends file name. The HTTPWebRequest will cause the MyFile.SaveAs to fail. Just wasted hours chasing one client working and one client not.
I just used Request.Files[0] instead of Request.Files["UploadedFile"] and while the OP was using straight ASP .NET and not MVC, if anyone wants to use this for MVC, you just need HttpPostedFileBase instead of HttpPostedFile.
23

You'll have to set the enctype attribute of the form to multipart/form-data; then you can access the uploaded file using the HttpRequest.Files collection.

1 Comment

My server form was on a master page and I could not add multipart/form-data (since then it would be on every page). A quick-and-dirty workaround was to add a hidden FileUpload control to the page. WebForms then added the multipart/form-data automatically. I had to do this because I was using a file input with Angular2 and couldn't use a server control in a component template.
9

use the HTML control with a runat server attribute

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

Then in asp.net Codebehind

 FileInput.PostedFile.SaveAs("DestinationPath");

There are also some 3'rd party options that will show progress if you intrested

3 Comments

Again, that's turning it into a server control. ;)
@ahwm The OP wanted to avoid the ASP .NET FileUpload control (<asp:FileUpload ID="fileUpload1" runat="server"></asp:FileUpload>) That is different than saying to not put a runat=server on an input field.
I take that to mean they don't want to use ASP.NET controls. Which includes the HtmlInputFile control.
8

Yes you can achive this by ajax post method. on server side you can use httphandler. So we are not using any server controls as per your requirement.

with ajax you can show the upload progress also.

you will have to read the file as a inputstream.

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

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

3 Comments

Maybe you should add the hint to add an fs.close() everything else might end up in unreadable files since they stay somehow open within IIS.
@mistapink Is the file stream not closed when the execution leaves the using block?
@Sebi it seems like almost 3 years ago it didn't. Didn't try it for a long time, so I can not give a definite answer here. I am sorry.
4

The Request.Files collection contains any files uploaded with your form, regardless of whether they came from a FileUpload control or a manually written <input type="file">.

So you can just write a plain old file input tag in the middle of your WebForm, and then read the file uploaded from the Request.Files collection.

Comments

4

As others has answer, the Request.Files is an HttpFileCollection that contains all the files that were posted, you only need to ask that object for the file like this:

Request.Files["myFile"]

But what happen when there are more than one input mark-up with the same attribute name:

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

On the server side the previous code Request.Files["myFile"] only return one HttpPostedFile object instead of the two files. I have seen on .net 4.5 an extension method called GetMultiple but for prevoious versions it doesn't exists, for that matter i propose the extension method as:

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

This extension method will return all the HttpPostedFile objects that have the name "myFiles" in the HttpFileCollection if any exists.

Comments

2

HtmlInputFile control

I've used this all the time.

2 Comments

That requires adding runat="server" which essentially turns it into a server control, which they didn't want to use.
@ahwm No, the OP didn't want to use the specific ASP .NET FileUpload control. That is different than saying they didn't want to use a server-side control, in general.
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();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.