Я даю пользователям возможность добавлять изображения для розничного продукта внутри модального окна «Добавить/редактировать продукт».
public class ProductModalViewModel
{
public ProductModalViewModel()
{
Product = new ProductDTO();
Images = new List<ProductImageViewModel>();
}
public ProductDTO Product { get; set; }
public List<ProductImageViewModel> Images { get; set; }
}
Каждое изображение продукта содержится в собственной ViewModel, как показано ниже:
public class ProductImageViewModel
{
public ProductImageViewModel()
{
ProductImage = new ProductImageDTO();
}
public ProductImageDTO ProductImage { get; set; }
[DataType(DataType.Upload)]
public IFormFile ImageFile { get; set; }
}
После отправки формы для сохранения продукта (и любых добавленных изображений) мой запрос зависает и отображается как «ожидающий» в инструментах разработки Chrome. Мое действие контроллера никогда не достигается.
Это происходит только тогда, когда я включаю ProductImage Fields/ViewModel/Logic в свой проект. Этого не происходило до добавления этой функциональности в модальное окно, и оно отлично работает, если я удалю все поля ProductImage Fields/ViewModel/Logic, а затем отправлю снова.
Есть ли что-то изначально неправильное с включением моего IFormFile во вложенную ViewModel? Или это может быть что-то другое. Остальная часть моего соответствующего кода приведена ниже.
[HttpPost]
public IActionResult SaveProduct([FromForm]ProductModalViewModel model)
{
//save code
}
<form id = "formSaveProduct" onsubmit = "SaveProduct(event)" enctype = "multipart/form-data">
//Other product fields removed for brevity
<div class = "row">
<div class = "col-md-12">
<ul class = "list-group" id = "image-list-group">
@for (int i = 0; i < Model.Images.Count(); i++)
{
<partial name = "_ImageListItem" for = "Images[i]" />
}
</ul>
</div>
</div>
</form>
<li class = "list-group-item my-1">
<input type = "hidden" asp-for = "ProductImage.Id" class = "image-id" />
<input type = "hidden" asp-for = "ProductImage.ProductId" class = "image-productid" />
<div class = "row">
<div class = "col-3">
<input type = "text" readonly asp-for = "ProductImage.Order" class = "image-order" />
</div>
<div class = "col-6">
<img src = "..\@Model.ProductImage.Path" class = "image-display" />
</div>
</div>
</li>
function SaveProduct(e) {
e.preventDefault(); // prevent standard form submission
$.ajax({
url: "@Url.Action("SaveProduct", "ProductManagement", new { Area = "Admin" })",
method: "post",
data: new FormData($('#formSaveProduct')[0]),
contentType: false,
processData: false,
cache: false,
success: function (result) {
//removed for brevity
}
});
}
Какое определение для ProductImageDTO
? Есть ли демо, чтобы воспроизвести вашу проблему? Есть ли ошибка на вкладке консоли веб-разработчика?
Во-первых, вам это не нужно
[DataType(DataType.Upload)]
public IFormFile ImageFile { get; set; }
поэтому вы можете изменить свой код на
public IFormFile ImageFile { get; set; }
И в свой сценарий вы должны добавить contentType
function SaveProduct(e) {
e.preventDefault(); // prevent standard form submission
$.ajax({
url: "@Url.Action("SaveProduct", "ProductManagement", new { Area = "Admin" })",
method: "post",
data: new FormData($('#formSaveProduct')[0]),
contentType: false,
processData: false,
cache: false,
contentType: "multipart/form-data", //here
success: function (result) {
if (result.success) {
$("#exampleModal").modal('toggle');
location.reload();
}
else {
$(".modal-body").html(result);
}
}
});
}
Спасибо за ответ. Я считаю, что добавление contentType приводит к тому, что [FromForm] в моем действии контроллера больше не работает. Запрос больше не зависает, но действие контроллера никогда не достигается. Должен ли я также вносить изменения в действие?
я думаю, вы можете использовать [FromBody]
На этот вопрос был прекрасно дан ответ в моем концептуальном вопросе в следующем посте:
для функции Ajax добавьте contentType: multipart/form-data и попробуйте еще раз, я не уверен, поможет это или нет.