在 ASP.NET Core 中上传带有参数的多个文件
Upload multiple files with parameters in ASP.NET Core
我的视图模型:
public class FileInfo
{
[Required]
[StringLength(50, ErrorMessage = "TitleErrorMessage", MinimumLength = 2)]
public string Title { get; set; }
[Required]
[StringLength(100, ErrorMessage = "DesErrorMessage", MinimumLength = 3)]
public string Description { get; set; }
[Required]
[DataType(DataType.Upload)]
public IFormFile File { get; set; }
}
以下为_UploadForm部分视图文件:
@model SessionStateTest.Models.FileInfo
<div class="form-group">
<label>Title</label>
<input class="form-control" asp-for="Title" />
</div>
<div class="form-group">
<label>Description</label>
<input class="form-control" asp-for="Description" />
</div>
<div class="form-group">
<label></label>
<input type="file" asp-for="File" />
</div>
在另一个视图中使用此代码:
<form asp-action="AddUploadForm" asp-controller="Home" method="Post">
<input type="submit" value="Add another file" class="btn btn-sm btn-primary" />
</form>
<form asp-action="Upload" asp-controller="Home" method="Post" enctype="multipart/form-data">
@foreach (var item in Model.Upload)
{
@(await Html.PartialAsync("_UploadForm", item))
}
<div class="col-xs-12">
<input type="submit" value="Upload" class="btn btn-sm btn-info" />
</div>
</form>
基本上,AddUploadForm
操作会向 Model.Upload
添加类型为 FileInfo
的新视图模型,这是我的主要视图模型。
问题是下面 Upload
操作中的列表 List<FileInfo> vm
完全是空的:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Upload(List<FileInfo> vm)
{
.... some other logic
return View();
}
我不想使用 multiple
属性,因为我想强制用户为每个文件提供标题和描述。
如有任何帮助,我们将不胜感激!
您使用 _UploadForm
的方法生成以下 html(让我们只关注 input
,因为这是最重要的部分)
<input class="form-control" name="Title" />
<input class="form-control" name="Description" />
<input type="file" name="File" />
...
<input class="form-control" name="Title" />
<input class="form-control" name="Description" />
<input type="file" name="File" />
... and so on
因此 name
属性仅包含 FileInfo
没有索引的模型属性名称,这仅适用于您的控制器需要单个模型的情况
public IActionResult Upload(FileInfo vm)
并且为了让您的 html 与您当前的控制器配合使用模型列表
public IActionResult Upload(List<FileInfo> vm)
应该是这样的
<!-- version 1 -->
<input class="form-control" name="[0].Title" />
<input class="form-control" name="[0].Description" />
<input type="file" name="[0].File" />
...
<input class="form-control" name="[1].Title" />
<input class="form-control" name="[1].Description" />
<input type="file" name="[1].File" />
... and so on
或
<!-- version 2 -->
<!-- the name before index must match parameter name in controller -->
<input class="form-control" name="vm[0].Title" />
<input class="form-control" name="vm[0].Description" />
<input type="file" name="vm[0].File" />
...
<input class="form-control" name="[1].Title" />
<input class="form-control" name="[1].Description" />
<input type="file" name="vm[1].File" />
... and so on
这可以通过使用标签助手和部分视图以稍微不同的方式来完成。您需要做的就是将部分视图的模型转换为列表并更新 asp-for
表达式。
_UploadForm.cshtml
@model List<SessionStateTest.Models.FileInfo>
@for (int i = 0; i < Model.Count; i++)
{
<div class="form-group">
<label>Title</label>
<input class="form-control" asp-for="@Model[i].Title" />
</div>
<div class="form-group">
<label>Description</label>
<input class="form-control" asp-for="@Model[i].Description" />
</div>
<div class="form-group">
<label></label>
<input type="file" asp-for="@Model[i].File" />
</div>
}
查看
<form asp-action="Upload" asp-controller="Home" method="Post" enctype="multipart/form-data">
@await Html.PartialAsync("_UploadForm", Model.Upload)
<div class="col-xs-12">
<input type="submit" value="Upload" class="btn btn-sm btn-info" />
</div>
</form>
它会像 版本 1 一样生成 html。
我的视图模型:
public class FileInfo
{
[Required]
[StringLength(50, ErrorMessage = "TitleErrorMessage", MinimumLength = 2)]
public string Title { get; set; }
[Required]
[StringLength(100, ErrorMessage = "DesErrorMessage", MinimumLength = 3)]
public string Description { get; set; }
[Required]
[DataType(DataType.Upload)]
public IFormFile File { get; set; }
}
以下为_UploadForm部分视图文件:
@model SessionStateTest.Models.FileInfo
<div class="form-group">
<label>Title</label>
<input class="form-control" asp-for="Title" />
</div>
<div class="form-group">
<label>Description</label>
<input class="form-control" asp-for="Description" />
</div>
<div class="form-group">
<label></label>
<input type="file" asp-for="File" />
</div>
在另一个视图中使用此代码:
<form asp-action="AddUploadForm" asp-controller="Home" method="Post">
<input type="submit" value="Add another file" class="btn btn-sm btn-primary" />
</form>
<form asp-action="Upload" asp-controller="Home" method="Post" enctype="multipart/form-data">
@foreach (var item in Model.Upload)
{
@(await Html.PartialAsync("_UploadForm", item))
}
<div class="col-xs-12">
<input type="submit" value="Upload" class="btn btn-sm btn-info" />
</div>
</form>
基本上,AddUploadForm
操作会向 Model.Upload
添加类型为 FileInfo
的新视图模型,这是我的主要视图模型。
问题是下面 Upload
操作中的列表 List<FileInfo> vm
完全是空的:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Upload(List<FileInfo> vm)
{
.... some other logic
return View();
}
我不想使用 multiple
属性,因为我想强制用户为每个文件提供标题和描述。
如有任何帮助,我们将不胜感激!
您使用 _UploadForm
的方法生成以下 html(让我们只关注 input
,因为这是最重要的部分)
<input class="form-control" name="Title" />
<input class="form-control" name="Description" />
<input type="file" name="File" />
...
<input class="form-control" name="Title" />
<input class="form-control" name="Description" />
<input type="file" name="File" />
... and so on
因此 name
属性仅包含 FileInfo
没有索引的模型属性名称,这仅适用于您的控制器需要单个模型的情况
public IActionResult Upload(FileInfo vm)
并且为了让您的 html 与您当前的控制器配合使用模型列表
public IActionResult Upload(List<FileInfo> vm)
应该是这样的
<!-- version 1 -->
<input class="form-control" name="[0].Title" />
<input class="form-control" name="[0].Description" />
<input type="file" name="[0].File" />
...
<input class="form-control" name="[1].Title" />
<input class="form-control" name="[1].Description" />
<input type="file" name="[1].File" />
... and so on
或
<!-- version 2 -->
<!-- the name before index must match parameter name in controller -->
<input class="form-control" name="vm[0].Title" />
<input class="form-control" name="vm[0].Description" />
<input type="file" name="vm[0].File" />
...
<input class="form-control" name="[1].Title" />
<input class="form-control" name="[1].Description" />
<input type="file" name="vm[1].File" />
... and so on
这可以通过使用标签助手和部分视图以稍微不同的方式来完成。您需要做的就是将部分视图的模型转换为列表并更新 asp-for
表达式。
_UploadForm.cshtml
@model List<SessionStateTest.Models.FileInfo>
@for (int i = 0; i < Model.Count; i++)
{
<div class="form-group">
<label>Title</label>
<input class="form-control" asp-for="@Model[i].Title" />
</div>
<div class="form-group">
<label>Description</label>
<input class="form-control" asp-for="@Model[i].Description" />
</div>
<div class="form-group">
<label></label>
<input type="file" asp-for="@Model[i].File" />
</div>
}
查看
<form asp-action="Upload" asp-controller="Home" method="Post" enctype="multipart/form-data">
@await Html.PartialAsync("_UploadForm", Model.Upload)
<div class="col-xs-12">
<input type="submit" value="Upload" class="btn btn-sm btn-info" />
</div>
</form>
它会像 版本 1 一样生成 html。