Я использую внешний класс для преобразования объектной переменной в переменную FormData. Проходят все ключи, кроме одного для объекта File.
Вот этот внешний класс: https://github.com/therealparmesh/object-to-formdata
Вот как я создаю объекты и превращаю их в FormData
var _documents = [];
for (var i = 0; i < arrayOfFiles.length; i++) {
var document = {
File: arrayOfFiles[i].file.nativeFile,
DocumentId: arrayOfFiles[i].documentId,
DocumentType: arrayOfFiles[i].documentName
};
_documents.push(document);
}
var uploadedInformation = {
LoanID: 1452465,
documents: _documents
};
var options = {
indices: true,
nulls: true
};
var a = objectToFormData(uploadedInformation, options);
for (var pair of a.entries()) {
console.info(pair[0] + ', ' + pair[1]);
}
jQuery.ajaxSettings.traditional = true;
$.ajax({
async: false,
cache: false,
contentType: false,
processData: false,
type: 'POST',
url: '@Url.Action("UploadFile", "Home")',
data: a
});
Код для контроллера:
[HttpPost]
[ActionName("UploadFile")]
public ActionResult UploadFile(UploadedInformation uploadedInformation)
{
_ = Request.Form;
return View();
}
Класс UploadedFile:
public class UploadedInformation
{
public long LoanID { get; set; }
public IEnumerable<Document> Documents { get; set; }
}
Класс документа:
public class Document
{
public HttpPostedFileBase File { get; set;}
public string DocumentId { get; set;}
public string DocumentType { get; set; }
}
Все элементы отлично вяжутся, кроме File.
Ключи и значения отладчика браузера:
LoanID, 1452465
documents[0][File], [object File]
documents[0][DocumentId], 1
documents[0][DocumentType], Passport
_=Request.Form также отображает только 3 ключа без documents[0][File]
Обновлять: Я поменял контроллер на
public ActionResult UploadFile(IEnumerable<HttpPostedFileBase> file, IEnumerable<string> documentType, IEnumerable<string>documentId, long loanId){...}
и _=Request.Form по-прежнему ничего не показывает с file, однако список файлов заполнен
Еще одно обновление:
Судя по всему, на этот раз элементы файлов отображаются только в _=Request.File
@StevieW На вкладке «Данные формы» написано: «Идентификатор займа: 1452465 документов [0] [Файл]: (двоичные) документы [0] [Идентификатор документа]: 1 документ [0] [Тип документа]: паспорт»
@StevieW я сделал обновление
Если в сетевом запросе отображается имя поля и (двоичный) индикатор, то он отправляется. Пробовали ли вы проверить Request.Files, чтобы убедиться, что входящий запрос зарегистрировал файлы не так, как вы ожидаете?
@StevieW Я написал несколько обновлений. Да, похоже, что в Request.File есть ключи, но они все еще не привязаны. Любые идеи, как это исправить?





Из-за того, как контроллер обрабатывает части запроса на загрузку файлов, я подозреваю, что вам может потребоваться внести некоторые коррективы в ваш процесс и учесть тот факт, что файлы отделяются от основного объекта.
Я включил некоторые корректировки в ваш код ниже (обратите внимание, это не тестировалось, поэтому вам, возможно, придется немного поэкспериментировать), предполагая, что файлы проходят в том же порядке, что и ваши документы, а затем просто запустите процесс сопоставления перед запуском вашего собственный процесс.
Код для контроллера:
[HttpPost]
[ActionName("UploadFile")]
public ActionResult UploadFile(List<HttpPostedFileBase> myFiles, UploadedInformation uploadedInformation)
{
for (var i = 0; i <uploadedInformation.Documents.Length; i++)
{
uploadedInformation.Documents[i].File = myFiles[i];
}
// Do stuff
return View();
}
В случае, если порядок файлов не может быть установлен, вы можете добавить имя файла к данным, чтобы облегчить сопоставление на стороне сервера.
Javascript
var _documents = [];
for (var i = 0; i < arrayOfFiles.length; i++) {
var document = {
File: arrayOfFiles[i].file.nativeFile,
FileName: arrayOfFiles[i].file.name,
DocumentId: arrayOfFiles[i].documentId,
DocumentType: arrayOfFiles[i].documentName
};
_documents.push(document);
}
То есть, по сути, разделить загрузку файла, а затем просто прикрепить его вручную в контроллере по идентификатору или имени файла? Честно говоря, я думал об этом решении, но хотел максимально избежать, потому что, как я вижу, оно создает возможности для ошибок, но я, вероятно, реализую его, если не найду, как это исправить. Спасибо!
Да, это почти все. сопоставление объекта HttpPostedFileBase с моделью должно позволить остальной части вашего процесса работать без дальнейших изменений.
Да, швы достаточно разумны
Как отправляется файл? часть [object File] мало что нам говорит, так как это, кажется, просто вывод журнала консоли, поэтому объект не будет выводиться в строку. Можете ли вы получить необработанный HTTP-запрос, который публикуется (при использовании Chrome откройте инструменты разработчика и перейдите в раздел «Сеть»)?