Я даю пользователям возможность добавлять изображения для розничного продукта в модале «Добавить / редактировать продукт».

Модальная ViewModel:

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

PartialView (ProductImage):

<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
        }
    });
}
1
Graham Meehan 28 Май 2019 в 04:39

2 ответа

Лучший ответ

На этот вопрос чудесно ответил мой концептуальный вопрос в следующем посте:

IFormFile как вложенное свойство ViewModel

0
Graham Meehan 29 Май 2019 в 11:08

Во-первых, вам это не нужно

[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);
            }
        }
    });
}
1
Tony Ngo 28 Май 2019 в 03:37
56334056