List имеет значение null для больших файлов. Воспроизводимость по желаниюC#

Место общения программистов C#
Ответить
Anonymous
 List имеет значение null для больших файлов. Воспроизводимость по желанию

Сообщение 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
Тип контента по-прежнему представляет собой многочастный поток.
РЕДАКТИРОВАТЬ 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
Это поведение можно воспроизвести по желанию. Вот клиентский код, который я использую. Поместите код сервера в какой-нибудь контроллер и посмотрите, что я имею в виду.
СТОП: Моя ошибка: я работаю над новой версией кода, которая использует XHR вместо FETCH для получения событий прогресса. К сожалению, «рабочий» код, который я использовал для демонстрации большой загрузки, по-прежнему имел ОТМЕНУ через 10 секунд. Да, я чувствую себя глупо. Моя вина :-(




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
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»