【发布时间】:2010-10-08 20:19:49
【问题描述】:
如何获取 ASP.net 网络表单 (v3.5) 以使用普通的旧 <input type="file" /> 发布文件?
我对使用 ASP.net FileUpload 服务器控件不感兴趣。
【问题讨论】:
标签: asp.net upload file-upload
如何获取 ASP.net 网络表单 (v3.5) 以使用普通的旧 <input type="file" /> 发布文件?
我对使用 ASP.net FileUpload 服务器控件不感兴趣。
【问题讨论】:
标签: asp.net upload file-upload
//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();
【讨论】:
是的,您可以通过 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();
}
}
}
}
【讨论】:
fs.close() 其他所有内容都可能以无法读取的文件结尾,因为它们在 IIS 中以某种方式保持打开状态。
这是一个不依赖任何服务器端控件的解决方案,就像 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
}
}
【讨论】:
Request.Files[0] 而不是Request.Files["UploadedFile"],而OP 使用的是直接的ASP .NET 而不是MVC,如果有人想将它用于MVC,你只需要HttpPostedFileBase 而不是HttpPostedFile.
正如其他人已经回答的那样,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"] 只返回一个 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 对象。
【讨论】:
您必须将form 的enctype 属性设置为multipart/form-data;
然后您可以使用HttpRequest.Files 集合访问上传的文件。
【讨论】:
在你的 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)));
}
}
【讨论】:
runat="server",它并不独立于 ASP.NET 的服务器内容
var fileUploaded = document.getElementById("myFile").files[0];,甚至可以使用readAsArrayBuffer:stackoverflow.com/questions/37134433/… 获取字节——但是您将在客户端处理所有这些字节吗? OP 希望完全避免 ASP .NET 控件而不是服务器端通信。 -1 给你。
使用带有 runat 服务器属性的 HTML 控件
<input id="FileInput" runat="server" type="file" />
然后在asp.net Codebehind中
FileInput.PostedFile.SaveAs("DestinationPath");
如果您有兴趣,还有一些3'rd party 选项会显示进度
【讨论】:
<asp:FileUpload ID="fileUpload1" runat="server"></asp:FileUpload>) 这与说不要在 input 字段上放置 runat=server 不同。
HtmlInputFile 控件。
Request.Files 集合包含随表单上传的所有文件,无论它们来自 FileUpload 控件还是手动编写的 <input type="file">。
所以你可以在你的 WebForm 中间写一个普通的旧文件输入标签,然后读取从 Request.Files 集合上传的文件。
【讨论】:
我一直都在用这个。
【讨论】:
runat="server",这实际上将其变成了他们不想使用的服务器控件。