У меня есть метод контроллера C#, который успешно принимает небольшие файлы, но когда я пытаюсь загрузить большой файл из клиента браузера, параметр «files» имеет значение null.
Я выполнил поиск в Интернете и добавил ограничение на размер запроса: -
[HttpPost]
[RequestSizeLimit(107374182400)]
public async Task PostFormData(List files, CancellationToken cancellationToken = default)
Я также пытался настроить ограничение в настройках приложения, json: -
"Kestrel": {
"Limits": {
"MaxRequestBodySize": 107374182400 // 100 GB example (1024*1024*1024)
}
}
Мне нужно сделать что-то еще?
Это JS-клиент: -
const abortControl = new AbortController();
const signal = abortControl.signal;
const fetchOpts = {signal:signal, method:'POST', body: fileHolder, cache:"no-cache"};
const response = fetch("https://localhost:7196/upload/PostFormData", fetchOpts).catch(
err => {
console.log("Upload failed: " + err.message);
return
})
if (signal.aborted) {
alert("Cancelled")
return
}
Размер файла — 10 737 418 240 байт — bigfile.txt
Тип контента по-прежнему представляет собой многочастный поток.
РЕДАКТИРОВАТЬ 1
Я хотел бы иметь возможность обрабатывать несколько файлов одновременно (полный код ниже). Тест на 10 ГБ был просто «тестом», чтобы доказать это. можно было бы сделать. Это редкое исключение, которое можно настроить.
Если я не могу использовать привязку [FromBody], что мне нужно изменить, если я выберу маршрут «Set MultipartBodyLengthLimit»?
[HttpPost]
[RequestSizeLimit(107374182400)]
public async Task PostFormData(List files, CancellationToken cancellationToken = default)
{
if (!Request.ContentType?.Contains("multipart/form-data") == true)
{
return BadRequest("Unsupported media type.");
}
if (files == null || files.Count maxTotalSize)
break;
}
if (totalBytes > maxTotalSize)
{
return BadRequest("Total File Size exceeds limit.");
}
var copyResults = new List();
var fileOptions = new FileStreamOptions()
{
Mode = FileMode.Create,
Access = FileAccess.ReadWrite,
Options = FileOptions.Asynchronous,
};
var loopOptions = new ParallelOptions { MaxDegreeOfParallelism = 3 };
await Parallel.ForEachAsync(files, loopOptions, async (file, _) =>
{
if (file.Length maxFileSize)
{
lock (_resultsLock)
{
copyResults.Add(new FileCopyStatus
{
FileName = file.FileName,
UploadStatus = (int)CopyStatus.Invalid,
Message = "File Size"
});
}
_logger.LogError("Invalid file copy for {file} prevented due to File Size", file.FileName);
}
// Check file.contentType and file.filename type
try
{
var filePath = Path.Combine(folder, file.FileName);
fileOptions.PreallocationSize = file.Length;
using (var stream = new FileStream(filePath, fileOptions))
{
await file.CopyToAsync(stream, cancellationToken);
}
lock (_resultsLock)
{
lock (_resultsLock)
{
copyResults.Add(new FileCopyStatus
{
FileName = file.FileName,
UploadStatus = (int)CopyStatus.Success
});
}
}
}
catch (TaskCanceledException)
{
lock (_resultsLock)
{
copyResults.Add(new FileCopyStatus
{
FileName = file.FileName,
UploadStatus = (int)CopyStatus.Cencelled
});
}
_logger.LogError("File copy for {file} cancelled.", file.FileName);
}
catch (Exception ex)
{
lock (_resultsLock)
{
copyResults.Add(new FileCopyStatus
{
FileName = file.FileName,
UploadStatus = (int)CopyStatus.Error,
Message = ex.Message
});
}
_logger.LogError(ex, "Error saving {file}", file.FileName);
}
});
if (cancellationToken.IsCancellationRequested)
{
}
return Ok(copyResults);
}
РЕДАКТИРОВАТЬ 2
Это поведение можно воспроизвести по желанию. Вот клиентский код, который я использую. Поместите код сервера в какой-нибудь контроллер и посмотрите, что я имею в виду.
body {
font-size: 14px;
}
#container {
position: relative;
display: flex;
width: 10em;
height: 10em;
padding: 0.9em;;
border: 1px solid black;
}
#div1 {
position: absolute;
top: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
background-color: lightblue;
}
#div2 {
--fade-time: 0;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0%;
background-repeat: no-repeat;
background-position: center;
background-size: cover;
background-image: url("data:image/svg+xml;utf8,
");
animation: pulseImage var(--fade-time) infinite;
}
body > p {
color: red;
font-size: 1.2em;
}
div > p {
font-weight: bold;
}
@keyframes pulseImage {
from {
opacity: 0;
}
to {
opacity: 0.7;
}
}
document.addEventListener("DOMContentLoaded", (e) => {
document.addEventListener('drop', function(e){ e.preventDefault() })
document.addEventListener('dragenter', function(e){ e.preventDefault(); e.dataTransfer.dropEffect = "none" })
document.addEventListener('dragover', function(e){ e.preventDefault(); e.dataTransfer.dropEffect = "none" })
const dropZone = document.getElementById("div2")
dropZone.addEventListener("dragenter", (e) => {
console.log("In enter " + e.target.id)
e.dataTransfer.dropEffect = "copy"
e.preventDefault()
e.stopPropagation()
document.getElementById("div2").style.setProperty("--fade-time","2.0s")
}, {capture: true})
dropZone.addEventListener("dragover", (e) => {
console.log("In over " + dropZone.id)
e.dataTransfer.dropEffect = "copy"
e.stopPropagation()
e.preventDefault()
})
dropZone.addEventListener("dragleave", (e) => {
console.log("In leave")
e.dataTransfer.dropEffect = "none"
e.preventDefault();
e.stopPropagation()
document.getElementById("div2").style.removeProperty("--fade-time")
}, {capture: true})
dropZone.addEventListener("drop", catchFiles)
})
async function catchFiles(e) {
e.preventDefault()
e.stopPropagation()
document.getElementById("div2").style.removeProperty("--fade-time")
console.log("File(s) dropped");
let fileHolder = new FormData()
let fileCount = 0
if (e.dataTransfer.items) {
[...e.dataTransfer.items].forEach((item, i) => {
if (item.kind === "file") {
const file = item.getAsFile()
console.log(`… file[${i}].name = ${file.name}`)
fileHolder.append("files", file, file.name)
fileCount++
}
});
} else {
[...e.dataTransfer.files].forEach((file, i) => {
console.log(`… file[${i}].name = ${file.name}`);
fileHolder.append("files", file, file.name)
fileCount++
});
}
if (fileCount == 0) {
alert("Zero files received")
return
}
alert("got " + fileCount + " files")
const abortControl = new AbortController();
const signal = abortControl.signal;
(function(ac){
var x = ac
setTimeout(
() => {
x.abort();
console.log("$*")
}, 10000)
})(abortControl)
const fetchOpts = {signal:signal, method:'POST', body: fileHolder, cache:"no-cache"};
const response = await fetch("https://localhost:7196/upload/PostFormData", fetchOpts).catch(
err => {
console.log("Upload failed: " + err.message);
return
});
if (signal.aborted) {
alert("Cancelled")
return
}
let resp
if (response.ok) {
resp = await response.json()
} else {
resp = await response.text()
}
console.log(resp)
}
File Drop Upload Example
Drag your file(s) into the Drop Zone
File Drop Zone
Подробнее здесь: https://stackoverflow.com/questions/798 ... le-at-will
List имеет значение null для больших файлов. Воспроизводимость по желанию ⇐ C#
Место общения программистов C#
1765756582
Anonymous
У меня есть метод контроллера C#, который успешно принимает небольшие файлы, но когда я пытаюсь загрузить большой файл из клиента браузера, параметр «files» имеет значение null.
Я выполнил поиск в Интернете и добавил ограничение на размер запроса: -
[HttpPost]
[RequestSizeLimit(107374182400)]
public async Task PostFormData(List files, CancellationToken cancellationToken = default)
Я также пытался настроить ограничение в настройках приложения, json: -
"Kestrel": {
"Limits": {
"MaxRequestBodySize": 107374182400 // 100 GB example (1024*1024*1024)
}
}
Мне нужно сделать что-то еще?
Это JS-клиент: -
const abortControl = new AbortController();
const signal = abortControl.signal;
const fetchOpts = {signal:signal, method:'POST', body: fileHolder, cache:"no-cache"};
const response = fetch("https://localhost:7196/upload/PostFormData", fetchOpts).catch(
err => {
console.log("Upload failed: " + err.message);
return
})
if (signal.aborted) {
alert("Cancelled")
return
}
Размер файла — 10 737 418 240 байт — bigfile.txt
Тип контента по-прежнему представляет собой многочастный поток.
[b]РЕДАКТИРОВАТЬ 1[/b]
Я хотел бы иметь возможность обрабатывать несколько файлов одновременно (полный код ниже). Тест на 10 ГБ был просто «тестом», чтобы доказать это. можно было бы сделать. Это редкое исключение, которое можно настроить.
Если я не могу использовать привязку [FromBody], что мне нужно изменить, если я выберу маршрут «Set MultipartBodyLengthLimit»?
[HttpPost]
[RequestSizeLimit(107374182400)]
public async Task PostFormData(List files, CancellationToken cancellationToken = default)
{
if (!Request.ContentType?.Contains("multipart/form-data") == true)
{
return BadRequest("Unsupported media type.");
}
if (files == null || files.Count maxTotalSize)
break;
}
if (totalBytes > maxTotalSize)
{
return BadRequest("Total File Size exceeds limit.");
}
var copyResults = new List();
var fileOptions = new FileStreamOptions()
{
Mode = FileMode.Create,
Access = FileAccess.ReadWrite,
Options = FileOptions.Asynchronous,
};
var loopOptions = new ParallelOptions { MaxDegreeOfParallelism = 3 };
await Parallel.ForEachAsync(files, loopOptions, async (file, _) =>
{
if (file.Length maxFileSize)
{
lock (_resultsLock)
{
copyResults.Add(new FileCopyStatus
{
FileName = file.FileName,
UploadStatus = (int)CopyStatus.Invalid,
Message = "File Size"
});
}
_logger.LogError("Invalid file copy for {file} prevented due to File Size", file.FileName);
}
// Check file.contentType and file.filename type
try
{
var filePath = Path.Combine(folder, file.FileName);
fileOptions.PreallocationSize = file.Length;
using (var stream = new FileStream(filePath, fileOptions))
{
await file.CopyToAsync(stream, cancellationToken);
}
lock (_resultsLock)
{
lock (_resultsLock)
{
copyResults.Add(new FileCopyStatus
{
FileName = file.FileName,
UploadStatus = (int)CopyStatus.Success
});
}
}
}
catch (TaskCanceledException)
{
lock (_resultsLock)
{
copyResults.Add(new FileCopyStatus
{
FileName = file.FileName,
UploadStatus = (int)CopyStatus.Cencelled
});
}
_logger.LogError("File copy for {file} cancelled.", file.FileName);
}
catch (Exception ex)
{
lock (_resultsLock)
{
copyResults.Add(new FileCopyStatus
{
FileName = file.FileName,
UploadStatus = (int)CopyStatus.Error,
Message = ex.Message
});
}
_logger.LogError(ex, "Error saving {file}", file.FileName);
}
});
if (cancellationToken.IsCancellationRequested)
{
}
return Ok(copyResults);
}
[b]РЕДАКТИРОВАТЬ 2[/b]
Это поведение можно воспроизвести по желанию. Вот клиентский код, который я использую. Поместите код сервера в какой-нибудь контроллер и посмотрите, что я имею в виду.
body {
font-size: 14px;
}
#container {
position: relative;
display: flex;
width: 10em;
height: 10em;
padding: 0.9em;;
border: 1px solid black;
}
#div1 {
position: absolute;
top: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
background-color: lightblue;
}
#div2 {
--fade-time: 0;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0%;
background-repeat: no-repeat;
background-position: center;
background-size: cover;
background-image: url("data:image/svg+xml;utf8,
");
animation: pulseImage var(--fade-time) infinite;
}
body > p {
color: red;
font-size: 1.2em;
}
div > p {
font-weight: bold;
}
@keyframes pulseImage {
from {
opacity: 0;
}
to {
opacity: 0.7;
}
}
document.addEventListener("DOMContentLoaded", (e) => {
document.addEventListener('drop', function(e){ e.preventDefault() })
document.addEventListener('dragenter', function(e){ e.preventDefault(); e.dataTransfer.dropEffect = "none" })
document.addEventListener('dragover', function(e){ e.preventDefault(); e.dataTransfer.dropEffect = "none" })
const dropZone = document.getElementById("div2")
dropZone.addEventListener("dragenter", (e) => {
console.log("In enter " + e.target.id)
e.dataTransfer.dropEffect = "copy"
e.preventDefault()
e.stopPropagation()
document.getElementById("div2").style.setProperty("--fade-time","2.0s")
}, {capture: true})
dropZone.addEventListener("dragover", (e) => {
console.log("In over " + dropZone.id)
e.dataTransfer.dropEffect = "copy"
e.stopPropagation()
e.preventDefault()
})
dropZone.addEventListener("dragleave", (e) => {
console.log("In leave")
e.dataTransfer.dropEffect = "none"
e.preventDefault();
e.stopPropagation()
document.getElementById("div2").style.removeProperty("--fade-time")
}, {capture: true})
dropZone.addEventListener("drop", catchFiles)
})
async function catchFiles(e) {
e.preventDefault()
e.stopPropagation()
document.getElementById("div2").style.removeProperty("--fade-time")
console.log("File(s) dropped");
let fileHolder = new FormData()
let fileCount = 0
if (e.dataTransfer.items) {
[...e.dataTransfer.items].forEach((item, i) => {
if (item.kind === "file") {
const file = item.getAsFile()
console.log(`… file[${i}].name = ${file.name}`)
fileHolder.append("files", file, file.name)
fileCount++
}
});
} else {
[...e.dataTransfer.files].forEach((file, i) => {
console.log(`… file[${i}].name = ${file.name}`);
fileHolder.append("files", file, file.name)
fileCount++
});
}
if (fileCount == 0) {
alert("Zero files received")
return
}
alert("got " + fileCount + " files")
const abortControl = new AbortController();
const signal = abortControl.signal;
(function(ac){
var x = ac
setTimeout(
() => {
x.abort();
console.log("$*")
}, 10000)
})(abortControl)
const fetchOpts = {signal:signal, method:'POST', body: fileHolder, cache:"no-cache"};
const response = await fetch("https://localhost:7196/upload/PostFormData", fetchOpts).catch(
err => {
console.log("Upload failed: " + err.message);
return
});
if (signal.aborted) {
alert("Cancelled")
return
}
let resp
if (response.ok) {
resp = await response.json()
} else {
resp = await response.text()
}
console.log(resp)
}
File Drop Upload Example
Drag your file(s) into the Drop Zone
File Drop Zone
Подробнее здесь: [url]https://stackoverflow.com/questions/79844581/listiformfile-is-null-for-large-files-reproducible-at-will[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия