Загрузить несколько файлов с параметрами в ASP.NET Core - PullRequest
0 голосов
/ 16 февраля 2019

Моя модель просмотра:

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 добавляет новую модель вида типа FileInfo к Model.Upload, которая является моей моделью основного вида.Проблема в том, что список List<FileInfo> vm в действии Upload ниже совершенно пуст:

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Upload(List<FileInfo> vm)
{
    .... some other logic 
    return View();
}

Я не хочу использовать атрибут multiple, потому что я хотел бы заставить пользователя предоставить заголовоки описание для каждого файла.

Любая помощь приветствуется!

1 Ответ

0 голосов
/ 16 февраля 2019

Ваш подход с использованием _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>
}

View

<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>

Он будет генерировать HTML, как в версии 1 .

...