Файл загрузки 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>