В ASP.NET Web API 2 ByteRangeStreamContent возвращает неверные данные при использовании с потоком из хранилища Azure - PullRequest
0 голосов
/ 29 марта 2019

Учитывая запрос диапазона, как это:

curl -r 0-16 https://example.com/api/blob/mobydick.txt -o moby0.txt -D -

Получаем:

Call me Ishmael.

А вот запрос Range:

curl -r 16-32 https://example.com/api/blob/mobydick.txt -o moby1.txt -D -

Мы все еще получаем:

Call me Ishmael.

Это следующий код (отредактированный для удаления получения большого двоичного объекта, учета запросов без заголовков диапазона или с открытым диапазоном и т. Д.):

Stream myBlobStream = await myBlob.OpenReadAsync();
HttpResponseMessage message = Request.CreateResponse(HttpStatusCode.PartialContent);
message.Content = new ByteRangeStreamContent(myBlobStream , range, myBlob.Properties.ContentType);
return message;

В примерах, которые я видел, нет необходимости вручную искать или устанавливать Положение потока, потому что (насколько я понимаю) это должно быть обработано ByteRangeStreamContent. Когда я пытаюсь вручную установить Положение потока в начало диапазона, результат будет противоречивым; иногда я получаю однобайтовый текстовый файл, а иногда весь файл, начинающийся с начала диапазона (т. е. конец диапазона игнорируется).

1 Ответ

0 голосов
/ 29 марта 2019

По крайней мере, на данный момент я решил эту проблему, возвращая ByteArrayContent вместо ByteRangeStreamContent.

// Including my setup of the range values this time:
    var range = Request.Headers.Range;

    long chunkLength = 2500000;
    long? beginRange = range.Ranges.First().From;
    long? endRange = range.Ranges.First().To;

    if (endRange == null)
    {
        if ((beginRange + chunkLength) > myBlob.Properties.Length)
        {
            endRange = myBlob.Properties.Length - 1;
        }
        else
        {
            endRange = beginRange + chunkLength;
        }
    }
    var blobStreamPosition = beginRange.Value;

// Set the stream position
    blobStream.Position = blobStreamPosition;

    int bytesToRead = (int)(endRange - blobStreamPosition + 1);

// Using BinaryReader for convenience
    BinaryReader binaryReader = new BinaryReader(blobStream);
    byte[] blobByteArray = binaryReader.ReadBytes(bytesToRead);
    message.Content = new ByteArrayContent(blobByteArray);

// Don't forget that now you have to set the content range header yourself:
    message.Content.Headers.ContentRange = new ContentRangeHeaderValue(blobStreamPosition, endRange.Value, myBlob.Properties.Length);
    message.Content.Headers.ContentType = new MediaTypeHeaderValue(myBlob.Properties.ContentType);

    binaryReader.Dispose();
    blobStream.Dispose();

Честно говоря, я не знаю, какие проблемы могут скрываться в этом решении; если ничего другого, этот байтовый массив означает, что он, вероятно, должен включать ограничение на размер частичного ответа, который он будет возвращать. Я бы предпочел использовать ByteRangeStreamContent, но, похоже, это работает для нас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...