我有一个ASP.NET MVC项目,用户可以在其中一次上传多个文件。视图中包含以下代码:
@using (Html.BeginForm("Edit",
"Bacteria",
FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
@Html.AntiForgeryToken()
<!--Other fields that are posted correctly to the db-->
<div class="">
<label class="control-label col-md-2">Attach New Files:</label>
<div class="col-md-10">
<input type="file" id="Attachment" name="Attachment" class="form-control" accept=".xls,.xlsx,.csv,.CSV,.png,.jpeg,.jpg,.gif,.doc,.docx,.pdf,.PDF" multiple />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
控制器中的方法是:
if (ModelState.IsValid)
{
db.Entry(bacteria).State = EntityState.Modified;
db.SaveChanges();
foreach (string file in Request.Files)
{
HttpPostedFileBase hpf = Request.Files[file];
var fileName = Path.GetFileName(hpf.FileName);
if (fileName == null || fileName == "")
{
break;
}
var subPath = "Attachments/Bacteria/" + bacteria.ID + "/";
bool exists = System.IO.Directory.Exists(Server.MapPath("~/" + subPath));
if (!exists)
{
System.IO.Directory.CreateDirectory(Server.MapPath("~/" + subPath));
}
var path = Path.Combine(subPath, fileName);
hpf.SaveAs(Server.MapPath("~/" + path));
BacteriaAttachment a = new BacteriaAttachment()
{
Name = fileName,
Bacteria = bacteria,
Link = path
};
db.BacteriaAttachments.Add(a);
db.SaveChanges();
}
}
如果我上传FileOne.png,FileTwo.png,FileThree.png; BacteriaAttachements表将获得3条新记录,它们都具有相同的名称(例如FileOne.png),链接和细菌ID。只有它们的ID(主键)是唯一的。服务器中仅上传了一个文件(例如FileOne.png)。
因此,不是上传三个文件,而是其中三个文件被上传了三次。
非常感谢您的帮助。
谢谢。
答案 0 :(得分:1)
在执行foreach (string file in Request.Files)
时,对于每次迭代,file
的值将是字符串值"Attachment"
,这是文件输入的名称。当用户从同一输入上载多个文件时,Request.Files
使用相同的键(即输入元素的名称,即“附件”)存储所有文件。现在,当您执行Request.Files["Attachment"]
时,它将只给您第一项( ,因为所有项都具有相同的键 )。对于循环的所有迭代,都是这样。
访问Request.Files
时,请勿使用基于名称的访问方法,使用基于索引的方法(Request.Files[zeroBasedindex]
)。
您可以使用for
循环正确地遍历集合,并使用基于索引的方法读取Request.Files
。
for(var i = 0; i < Request.Files.Count; i++)
{
HttpPostedFileBase hpf = Request.Files[i];
// Your existing code to save hpf.
}
我个人始终将HttpPostedFileBase
的集合用作我的HttpPost动作方法参数或作为我的视图模型中的属性(我将使用参数作为HttpPost动作方法)并将其循环。要记住的重要一点是,您的参数/属性名称应与用于文件上传的输入名称相匹配。
public ActionResult Save(List<HttpPostedFileBase> attachment)
{
foreach(var hpf in attachment)
{
// to do : save hpf
}
// to do : return something
}
答案 1 :(得分:0)
穆达萨尔·艾哈迈德·汗(Mudassar Ahmed Khan)在这里的解释非常好: https://www.aspsnippets.com/Articles/MVC-HttpPostedFileBase-multiple-files-Upload-multiple-files-using-HttpPostedFileBase-in-ASPNet-MVC.aspx
您应该考虑在控制器方法中使用
List<HttpPostedFileBase>
作为方法参数。然后遍历每个。如下所示;
foreach (HttpPostedFileBase postedFile in postedFiles)
{
if (postedFile != null)
{
string fileName = Path.GetFileName(postedFile.FileName);
希望这会有所帮助!