Reference
The members of the control that ships with ASP.NET Web Forms, what each one is for, and the two things its official documentation does not cover: restricting the file picker, and the size ceiling.
Members
Nine members do the work. Everything else the control exposes is inherited from WebControl.
| Member | Purpose |
HasFile | True when a single file was posted. Test this before touching SaveAs. |
HasFiles | The multi-file equivalent, for use with AllowMultiple. |
PostedFile | The underlying HttpPostedFile - use it for ContentLength and ContentType. |
PostedFiles | The collection of posted files when multiple selection is on. |
AllowMultiple | Renders multiple on the input so the picker accepts several files. |
FileName | The name supplied by the browser. See the warning below before using it. |
FileBytes | The whole file as a byte array. Fine for small files; it materialises everything in memory. |
FileContent | A Stream over the posted content - prefer this to FileBytes for anything large. |
SaveAs(path) | Writes the upload to an absolute path on the server. |
One file
<asp:FileUpload ID="FileUpload1" runat="server" />
<asp:Button ID="Upload" runat="server" Text="Upload" OnClick="Upload_Click" />
protected void Upload_Click(object sender, EventArgs e)
{
if (!FileUpload1.HasFile) return;
// Do NOT build the path from FileUpload1.FileName - see the warning below.
var safeName = Path.GetRandomFileName() + Path.GetExtension(FileUpload1.FileName);
FileUpload1.SaveAs(Path.Combine(Server.MapPath("~/App_Data/uploads"), safeName));
}
Several files
<asp:FileUpload ID="FileUpload1" runat="server" AllowMultiple="true" />
if (FileUpload1.HasFiles)
foreach (var posted in FileUpload1.PostedFiles)
posted.SaveAs(Path.Combine(root, Path.GetRandomFileName()));
Restricting the picker with accept
There is no Accept property, which is why this is hard to find - but the control passes unknown attributes straight through to the rendered <input>. Both of these work:
<%-- in markup --%>
<asp:FileUpload ID="FileUpload1" runat="server" accept="image/png" />
<%-- or from code --%>
FileUpload1.Attributes["accept"] = "image/*";
Both render as <input type="file" ... accept="image/png" />. Remember what accept is: a hint that filters the file picker. It is not validation - a determined user can still post anything, so check the file again on the server.
Two warnings worth repeating
Do not trust FileName. Microsoft's own documentation is blunt about this: use it for display and logging only, and HTML-encode it even then. It is a string the browser supplied, so treat it as hostile input and generate your own storage name.
There is a size ceiling and it is lower than you think. The upload is one ordinary form post, so it must fit inside maxRequestLength (4 MB by default) and IIS's maxAllowedContentLength. Raising them raises the limit for every request on the site. Uploading large files covers the whole chain, and the troubleshooting page maps the errors you get when one of them bites.
When the built-in control stops being enough
Everything above is a normal form post: no progress, no resume, no drag and drop, and one request per upload. That is genuinely fine for a CV or a logo. <asp:FileUpload> vs AjaxUploader sets out exactly where the line is - and argues both sides.