Сбой пользовательского HttpContent при загрузке
У меня есть кроссплатформенная библиотека (.net Framework 4.6.2, .net стандарт 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 ответ
Решение
Код ниже должен работать. Кажется, вы использовали неверные параметры
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);
}