Сбой пользовательского HttpContent при загрузке - PullRequest
0 голосов
/ 14 октября 2018

У меня есть кроссплатформенная библиотека (.net framework 4.6.2, .net standard 2.0 и uwp).Я создал прогрессивный потоковый контент для загрузки.

В .net framework и .net standard все работает отлично, а в UWP - нет.В UWP каждый раз он возвращает 500 server error (internal).

Когда я пытаюсь загрузить без ProgressableStreamContent, все работает хорошо в UWP.

вот мой класс:

internal class ProgressableStreamContent : HttpContent
{
    private const int defaultBufferSize = 100 * 1024;

    private HttpContent content;
    private readonly int _bufferSize;
    public UploadProgress UploaderProgress { get; internal set; }

    private readonly Action<UploadProgress> progress;
    public ProgressableStreamContent(HttpContent content, Action<UploadProgress> progress) : this(content, defaultBufferSize, progress) { }
    public ProgressableStreamContent(HttpContent content, int bufferSize, Action<UploadProgress> progress)
    {
        if (bufferSize <= 0)
            throw new ArgumentOutOfRangeException("bufferSize");

        this.content = content ?? throw new ArgumentNullException("content");
        if (bufferSize < 5120)
            bufferSize = defaultBufferSize;
        _bufferSize = bufferSize;
        this.progress = progress;

        foreach (var h in content.Headers)
        {
            Headers.Add(h.Key, h.Value);
        }
    }

    protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
    {
        return Task.Run(async () =>
        {
            var buffer = new byte[_bufferSize];
            TryComputeLength(out var size);
            var uploadedBytes = 0;


            using (var inputStream = await content.ReadAsStreamAsync())
            {
                while (true)
                {
                    var length = await inputStream.ReadAsync(buffer, 0, buffer.Length);
                    if (length <= 0) break;
                    uploadedBytes += length;
                    Invoke(uploadedBytes, size);
                    await stream.WriteAsync(buffer, 0, length);
                    await stream.FlushAsync();
                }
            }
            await stream.FlushAsync();
        });
    }
    void Invoke(long bytes, long size)
    {
        if (UploaderProgress == null)
            UploaderProgress = new UploadProgress();
        UploaderProgress.FileSize = size;
        UploaderProgress.UploadState =  size == bytes ? UploadState.Uploaded : UploadState.Uploading;
        UploaderProgress.UploadedBytes = bytes;
        progress?.Invoke(UploaderProgress);
    }
    protected override bool TryComputeLength(out long length)
    {
        length = content.Headers.ContentLength.GetValueOrDefault();
        return true;
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            content.Dispose();
        }
        base.Dispose(disposing);
    }
}

И как мне его использовать:

        using (var client = new HttpClient())
        {
            var requestContent = new MultipartFormDataContent("UPLOAD ID");
            byte[] fileBytes = null;// some image
            var imgCnt = new ByteArrayContent(fileBytes);
            imgCnt.Headers.Add("Content-Transfer-Encoding", "binary");
            imgCnt.Headers.Add("Content-Type", "application/octet-stream");

            var progressContent = new ProgressableStreamContent(imgCnt, 1024, progress);

            requestContent.Add(progressContent, "photo", $"{Path.GetRandomFileName()}.jpg");
            var req = await client.PostAsync(new Uri("SOME URI"), requestContent);

        }

1 Ответ

0 голосов
/ 14 октября 2018

Код ниже должен работать.Кажется, вы использовали неверные параметры

    using (var client = new HttpClient())
    {
        var requestContent = new MultipartFormDataContent("UPLOAD ID");
        byte[] fileBytes = null;// some image
        var imgCnt = new ByteArrayContent(fileBytes);
        imgCnt.Headers.Add("Content-Transfer-Encoding", "binary");
        imgCnt.Headers.Add("Content-Type", "application/octet-stream");

        requestContent.Add(imgCnt, "photo", $"{Path.GetRandomFileName()}.jpg");
        var progressContent = new ProgressableStreamContent(requestContent, 1024, progress);

        var req = await client.PostAsync(new Uri("SOME URI"), progressContent);

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