Файл загрузки Kendo отправляет ноль в контроллере, когда я отправляю другие значения в качестве параметров

Это ситуация: у меня есть форма, которая, когда я нажимаю кнопку отправки, отправляет файл с элементом управления загрузкой кендо, а действие метода контроллера получает этот файл в параметре с помощью HttpPostedFileBase.

Это мой HTML-код:

@using (Html.BeginForm("ConfirmarOposicion", "Gestion", FormMethod.Post, new { @id = "Frm-login", role = "form", @class = "form-horizontal" }))
{
    @(Html.Kendo().Upload()
        .Name("files")
    )

    <button class="btn btn-success" type="submit" id="confirm" >Confirm</button>
}

И это мой контроллер:

public async Task<ActionResult> ConfirmarOposicion(IEnumerable<HttpPostedFileBase> files)
{
    // Here the parameter files is not null..
}

Здесь работает все хорошо до сих пор. Проблема в том, когда я пытаюсь отправить больше значений в качестве параметра в тот же метод контроллера. Другие значения, которые я хочу отправить, это массив, а другое число. Это два значения, которые я пытаюсь отправить с ajax в javaScript.

Это мой код javaScript, когда я пытаюсь отправить эти два дополнительных значения:

$("#confirm").click(function () {
        var numMarca = $("#numMarca").val()
        var idsToSend = [];
        var grid = $("#Grid2").data("kendoGrid")
        var ds = grid.dataSource.view();
        for (var i = 0; i < ds.length; i++) {
            var row = grid.table.find("tr[data-uid='" + ds[i].uid + "']");
            var checkbox = $(row).find(".checkbox");
            if (checkbox.is(":checked")) {
                idsToSend.push(ds[i].DescMarca);
                idsToSend.push(ds[i].IntencionOposicion = 1);
            } else {
                idsToSend.push(ds[i].DescMarca);
            }
        }

        $.ajax({
            url: '@Url.Action("ConfirmarOposicion", "Gestion")',
            data: { ids: idsToSend, marca: numMarca },
            type: 'POST',
            dataType: "json",
            success: function (data) {

            }
        });

Когда я нажимаю кнопку отправки, эти два значения отправляются в тот же контроллер, который я отправляю во входной файл.

И это мой контроллер сейчас:

public async Task<ActionResult> ConfirmarOposicion(IEnumerable<HttpPostedFileBase> files, string[] ids, string marca)
{
    // here the array ids and the value of marca is not null, but the parameter files it is null

}

И это проблема, которая у меня есть. Мне нужно отправить все эти значения в том же методе действия контроллера. Как я могу это сделать?

2 ответа

Проблема: есть с этой строкой кода data: { ids: idsToSend, marca: numMarca },Вы вручную строите объект данных только с двумя параметрами, а не обрабатываете загруженные файлы, поэтому данные файла теряются.

Решение: Построить FormData объект, а затем вставьте в него все необходимые данные, включая загруженные файлы, и отправьте этот объект на сервер.

var formData = new FormData();
var file_data = $('#files')[0].files; // for multiple files if only single file use $('#files')[0].files[0] and skip the loop.
for(var i = 0;i<file_data.length;i++){
    formData.append("file_"+i, file_data[i]);
}    
formData.append('ids', idsToSend);
formData.append('marca', numMarca );

$.ajax({
    url: '@Url.Action("ConfirmarOposicion", "Gestion")',
    data: formData ,  // pass the formData object to server.
    type: 'POST',
    processData: false,
    contentType: false,
    dataType: "json",
    success: function (data) {

    }
 });

Замечания: $('#files') выбирает ваш файл управления, .Name("files") в синтаксисе кендо устанавливает идентификатор элемента управления файлом files,

Изменить: я добавил processData: false, а также contentType: false, в параметры AJAX. Кредиты на этот ответ

Если для processData задано значение false, вы не сможете автоматически преобразовывать данные в строку запроса в jQuery. Смотрите документы для получения дополнительной информации.

Настройка contentType значение false является обязательным, поскольку в противном случае jQuery установит его неправильно.

Используйте rawFile, чтобы получить фактически загружаемый файл. В моем случае onUpload срабатывает для каждого файла.

      // JavaScript
function setupUpload() {
    // this example, I use filetemplate to prompt the user for file attributes
    $("#fileOrderDocuments").kendoUpload({
        async: {
            saveUrl: "/Order/ValidateUploadDocuments",
            autoUpload: false
        },
        template: kendo.template($('#fileTemplate').html()),
        multiple: true,
        upload: onUpload,
        validation: {
            allowedExtensions: [".pdf"],
            maxFileSize: 25194304
        },
        success: onSuccess,
        select: onSelect
    });
}

function onSelect() {

}

function onSuccess(data) {
// triggered after each file is uploaded
}

    function onUpload(e) {
    // expect exactly 1 file since async upload will be triggered for each file
        if (!e.files || e.files.length != 1) return;
    
        var formData = new FormData();
        formData.append("files", e.files[0].rawFile);  // use rawFile to access file
        formData.append("orderId", orderId);
    
        $.ajax({
            url: "/Order/UploadDocuments",
            data: formData,
            type: 'POST',
            processData: false,
            contentType: false,
            success: function (data) {
                console.log(data);
            },
            error: function (e) {
                console.log(e);
            }
        });
    };
    
    // .Net Core Controller - Order Actions
    [HttpPost]
    public ActionResult UploadDocuments(IEnumerable<IFormFile> files, int orderId)
            {
                if (files != null && orderId > 0)
                {
                    foreach (var file in files)
                    {
    _documentService.SaveDocument(file, orderId);
                    }
                }
    
                return Json(Ok);
            }

// Kendo template in cshtml Razor page to customize file upload

<script id="fileTemplate" type="text/x-kendo-template">
    <div class="row m-0">
        <span class='k-progress'></span>
    </div>
    <div class="row m-0 w-100">
        <div class="col-1 p-0">
            <span class="k-file-extension-wrapper top-0">
                <span class="k-file-extension">pdf</span>
                <span class="k-file-state"></span>
            </span>
        </div>
        <div class="col-5">
            <span class="k-file-name-size-wrapper">
                <span class="k-file-name">#=name#</span>
                <span class="k-file-size">#=size# bytes</span>
            </span>
        </div>
        <div class="col-5">
            <span id="selectOrderType">
                <div>Select Document Type:</div>
                <div>
                    <select class="js-doc-type">
                        <option value="1">Unsigned Document</option>
                        <option value="2">Signed Document</option>
                    </select>
                </div>
            </span>
        </div>
        <div class="col-1 p-0">
            <strong class="k-upload-status float-right">
                <button type="button" class="k-button k-upload-action" aria-label="Remove">
                    <span class="k-icon k-i-close k-i-x" title="Remove"></span>
                </button>
            </strong>
        </div>
    </div>
</script>
Другие вопросы по тегам