Поскольку тело запроса это поток без поиска - его можно прочитать только один раз, я не могу просто использовать метод Stream.Seek.
Вот что я пробовал:
Код: Выделить всё
private const ushort DefaultBufferSize = 4096;
Код: Выделить всё
private protected async Task ReadRangedContentAsync(Func readCallback)
{
if (!Request.HasFormContentType ||
!MediaTypeHeaderValue.TryParse(Request.ContentType, out var contentType) ||
!contentType.Boundary.HasValue ||
!Request.Headers.TryGetValue(HeaderNames.ContentRange, out var contentRangeValues) ||
!ContentRangeHeaderValue.TryParse(contentRangeValues.First(), out var contentRange) ||
!contentRange.HasRange)
{
return new Result(HttpStatusCode.UnsupportedMediaType);
}
var offset = contentRange.From.Value;
var length = contentRange.To.Value - offset + 1;
var reader = new MultipartReader(contentType.Boundary.Value, Request.Body);
var section = await reader.ReadNextSectionAsync();
if (section is null)
return new Result(HttpStatusCode.BadRequest);
var buffer = new byte[length];
await SkipBytesAsync(section.Body, offset);
await ReadBytesAsync(section.Body, buffer);
return await readCallback(buffer);
}
Код: Выделить всё
private static async Task SkipBytesAsync(Stream stream, long bytesToSkip)
{
var trashBin = new byte[DefaultBufferSize];
while (bytesToSkip != 0)
{
// TODO: Add number overflow check.
var count = (int)Math.Min(trashBin.LongLength, bytesToSkip);
bytesToSkip -= await stream.ReadAsync(trashBin, 0, count);
}
}
Код: Выделить всё
private static async Task ReadBytesAsync(Stream stream, byte[] buffer)
{
int bytesRead;
var totalBytesRead = 0;
while (totalBytesRead < buffer.Length)
{
var length = Math.Min(DefaultBufferSize, buffer.Length - totalBytesRead);
var memory = buffer.AsMemory(totalBytesRead, length);
bytesRead = await stream.ReadAsync(memory);
if (bytesRead is 0)
break;
totalBytesRead += bytesRead;
}
}
Подробнее здесь: https://stackoverflow.com/questions/791 ... p-net-core
Мобильная версия