在ASP.net中上载文件而不使用FileUpload服务器控件

在ASP.net中上载文件而不使用FileUpload服务器控件,asp.net,upload,file-upload,Asp.net,Upload,File Upload,如何获得ASP.net web表单(v3.5)以使用普通的旧发布文件 我对使用ASP.net文件上载服务器控件不感兴趣。 我一直在使用它。使用带有runat server属性的HTML控件 <input id="FileInput" runat="server" type="file" /> 如果您感兴趣,还有一些选项将显示进度,您必须将表单的enctype属性设置为多部分/表单数据; 然后,您可以使用HttpRequest.Files集合访问上载的文件。Request.File

如何获得ASP.net web表单(v3.5)以使用普通的旧
发布文件

我对使用ASP.net文件上载服务器控件不感兴趣。


我一直在使用它。

使用带有runat server属性的HTML控件

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

如果您感兴趣,还有一些选项将显示进度,您必须将
表单的
enctype
属性设置为
多部分/表单数据

然后,您可以使用
HttpRequest.Files
集合访问上载的文件。

Request.Files集合包含随表单上载的任何文件,无论这些文件是来自文件上载控件还是手动编写的

<>你可以在你的Web窗体中间写一个普通的旧文件输入标签,然后在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>

这是一个不依赖任何服务器端控制的解决方案,就像OP在问题中所描述的那样

客户端HTML代码:

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

是的,您可以通过ajax post方法实现这一点。在服务器端,您可以使用httphandler。 因此,我们没有按照您的要求使用任何服务器控件

使用ajax,您还可以显示上载进度

您必须以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);
        }
    } 
示例代码

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

正如其他人所回答的,Request.Files是一个HttpFileCollection,其中包含所有已发布的文件,您只需向该对象请求文件,如下所示:

Request.Files["myFile"]
但是,如果有多个输入标记具有相同的属性名称,会发生什么情况:

Select file 1 <input type="file" name="myFiles" />
Select file 2 <input type="file" name="myFiles" />
选择文件1
选择文件2
在服务器端,前面的代码请求.Files[“myFile”]只返回一个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);
            }
        }
}
公共静态IEnumerable GetMultiple(此HttpFileCollection pCollection,字符串pName)
{
for(int i=0;i

此扩展方法将返回HttpFileCollection中所有名为“myFiles”的HttpPostedFile对象(如果存在)。

@mathieu,遗憾的是您的变体使用了
runat=“server”
,它与ASP.NET的服务器无关。如果有1个以上的输入,并且您希望对这两组文件执行单独的功能,那么它将为所有文件返回相同的文件名,从而多次保存第一个文件。“你知道怎么克服它吗?”玛蒂娜检查是否保存了多个files@DanielJ. 如果以后要对文件执行任何操作,即将其存储在数据库中,则不可能不使用代码隐藏。当然,您可以使用纯JavaScript获取输入文件:
var fileupload=document.getElementById(“myFile”).files[0]
甚至可以使用
readAsArrayBuffer
获取字节:-但是在客户端如何处理这些字节呢?OP希望完全避免ASP.NET控件而不是服务器端通信-1。这需要添加
runat=“server”
,这实际上会将其转换为服务器控件,而他们不想使用该控件。@ahwm不,OP不想使用特定的ASP.NET文件上载控件。这与通常说他们不想使用服务器端控件不同。同样,这将把它变成服务器控件@ahwm OP希望避免ASP.NET文件上载控件(
),这不同于说不要在
输入
字段上放置
runat=server
。我认为这意味着他们不想使用ASP.NET控件。其中包括
HtmlInputFile
控件。也许您应该添加提示以添加
fs.close()
其他所有内容都可能以无法读取的文件结束,因为它们在IIS中以某种方式保持打开状态。@mistapink是执行离开使用块时文件流没有关闭吗?@Sebi看起来差不多3年前它没有关闭。很久没有试过了,所以我在这里不能给出一个明确的答案。很抱歉。请注意HTTPWebRequest调用在MyFile.FileName中发送完整文件路径。WebClient调用只发送文件名。HTTPWebRequest将导致MyFile.SaveAs失败。我只是用
Request.Files[0]
而不是
Request.Files[“UploadedFile”]
来代替,虽然OP使用的是纯ASP.NET而不是MVC,但如果有人想用它来实现MVC,您只需要
HttpPostedFileBase
而不是
HttpPostedFile
。我的服务器表单位于母版页上,无法添加多部分/表单数据(因为那时它将位于每页上)。一个快速而肮脏的解决方法是在页面中添加一个隐藏的FileUpload控件。WebForms然后自动添加多部分/表单数据。我必须这样做,因为我使用的是Angular2的文件输入,不能在组件模板中使用服务器控件。
//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();
Select file 1 <input type="file" name="myFiles" />
Select file 2 <input type="file" name="myFiles" />
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);
            }
        }
}
//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();