Как добавлять значения динамических полей с картинками в бд

Есть ViewModel, которая содержит свойство

public Dictionary<string, IFormFile> Photos { get; set; }

Есть HTML-разметка, которая содержит несколько похожих полей формы для загрузки изображений (количество их не статично, может быть и 0, а может и 10, и 20, и больше, но разметка для всех одна, только ключ меняется).

<div class="custom-file">
     <input type="file" asp-for="Photos[key]" class=" custom-file-input form-control full">
     <label class="custom-file-label form-control" asp-for="Photos[key]">Выберите изображение..</label>
</div>

Метод контроллера:

[HttpPost]
public async Task<ActionResult> CreateEditContract(ContractViewModel contractViewModel)
{
    string contractNumber = $"{contractViewModel.Contract.NumYear}-{contractViewModel.Contract.Place}-{contractViewModel.Contract.Number}";
        foreach (var p in contractViewModel.Photos)
        {
            string uniqueFileName = null;
            if (p.Value != null)
            {
                string uploadsFolder = Path.Combine(_hostingEnvironment.WebRootPath,
                    $"images\photos-on-monuments\{contractNumber}");
                DirectoryInfo dirInfo = new DirectoryInfo(uploadsFolder);
                if (!dirInfo.Exists)
                    dirInfo.Create();
                uniqueFileName = Guid.NewGuid().ToString() + $"_{contractNumber}_{contractViewModel.Photos.FileName}";
                string filePath = Path.Combine(uploadsFolder, uniqueFileName);
                using (var fileStream = new FileStream(filePath, FileMode.Create))
                {
                    await p.Value.CopyToAsync(fileStream);
                }
            }
            if (p.Key.Contains('P'))
                contractViewModel.Portraits[p.Key].PhotoPath = uniqueFileName;
            else if (p.Key.Contains('M'))
                contractViewModel.Medallions[p.Key].PhotoPath = uniqueFileName;
        }
    }
    _servicesManager.Contracts.SaveViewModelToDB(contractViewModel);
    return RedirectToAction("Index");
}

Метод контроллера с одним полем для загрузки изображения (вместо коллекции) и без цикла for работает корректно, но если брать коллекцию - начинается ерунда. При нажатии кнопки submit в контроллер поступает модель со значением Photos.Count() = 0. Даже если изначально у ViewModel.Photos и были какие-либо значения, то они тоже удаляются. Как корректно можно записать значения из нескольких полей для загрузки изображений?


Ответы (1 шт):

Автор решения: Aliaksandra Manulik

Получилось решить проблему через создание дополнительной ViewModel.

public class PhotoViewModel
{
    [BindProperty]
    public IFormFile Image { get; set; }
    public string PhotoKey { get; set; }

}

А в основной модели я прописала коллекцию как public List<PhotoViewModel> Photos { get; set; } Теперь при заполнении формы у меня остались те же поля для загрузки изображения, но еще добавилось скрытое поле для ключа (такой подход с Dictionary не заработал, поэтому пришлось выкручиваться так). Разметка HTML:

<div class="custom-file">
    <input asp-for="Photos[p].PhotoKey" type="hidden" value=@keyP />
    <input type="file" asp-for="Photos[p].Image" class=" custom-file-input form-control full">
    <label class="custom-file-label form-control" asp-for="Photos[p].Image">Выберите изображение...</label>
</div>
→ Ссылка