gpt4 book ai didi

C#:HttpClient,将多个文件作为 MultipartFormDataContent 上传时的文件上传进度

转载 作者:行者123 更新时间:2023-11-30 13:25:44 28 4
gpt4 key购买 nike

我正在使用此代码上传多个文件并且运行良好。它使用现代 httpclient 库。

public async Task<string> PostImages (int platform, string url, List<byte []> imageList)
{
try {
int count = 1;
var requestContent = new MultipartFormDataContent ();

foreach (var image in imageList) {
var imageContent = new ByteArrayContent (image);
imageContent.Headers.ContentType = MediaTypeHeaderValue.Parse ("image/jpeg");
requestContent.Add (imageContent, "image" + count, "image.jpg");
count++;
}
var cookieHandler = new NativeCookieHandler ();
var messageHandler = new NativeMessageHandler (false, false, cookieHandler);
cookieHandler.SetCookies (cookies);
using (var client = new HttpClient (messageHandler)) {
client.DefaultRequestHeaders.TryAddWithoutValidation ("User-Agent", GetUserAgent (platform));
using (var r = await client.PostAsync (url, requestContent)) {
string result = await r.Content.ReadAsStringAsync ();
System.Diagnostics.Debug.WriteLine ("PostAsync: " + result);
return result;
}
}
} catch (Exception e) {
System.Diagnostics.Debug.WriteLine (e.Message);
return null;
}
}

现在我需要上传文件时的进度。我在谷歌搜索,发现我需要使用 ProgressStreamContent

https://github.com/paulcbetts/ModernHttpClient/issues/80

由于 ProgressStreamContent 包含一个采用流的构造函数,我将 MultipartFormDataContent 转换为流并在其构造函数中使用它。但是,它不起作用。上传失败。我认为这是因为它是所有文件的流,这不是我的后端所期望的。

public async Task<string> PostImages (int platform, string url, List<byte []> imageList)
{
try {
int count = 1;
var requestContent = new MultipartFormDataContent ();
// here you can specify boundary if you need---^
foreach (var image in imageList) {
var imageContent = new ByteArrayContent (image);
imageContent.Headers.ContentType = MediaTypeHeaderValue.Parse ("image/jpeg");
requestContent.Add (imageContent, "image" + count, "image.jpg");
count++;
}
var cookieHandler = new NativeCookieHandler ();
var messageHandler = new NativeMessageHandler (false, false, cookieHandler);
cookieHandler.SetCookies (RestApiPaths.cookies);


var stream = await requestContent.ReadAsStreamAsync ();

var client = new HttpClient (messageHandler);
client.DefaultRequestHeaders.TryAddWithoutValidation ("User-Agent", RestApiPaths.GetUserAgent (platform));

var request = new HttpRequestMessage (HttpMethod.Post, url);

var progressContent = new ProgressStreamContent (stream, 4096);
progressContent.Progress = (bytes, totalBytes, totalBytesExpected) => {
Console.WriteLine ("Uploading {0}/{1}", totalBytes, totalBytesExpected);
};

request.Content = progressContent;

var response = await client.SendAsync (request);
string result = await response.Content.ReadAsStringAsync ();

System.Diagnostics.Debug.WriteLine ("PostAsync: " + result);

return result;

} catch (Exception e) {
System.Diagnostics.Debug.WriteLine (e.Message);
return null;
}
}

我应该在这里做什么才能使它正常工作?感谢任何帮助

最佳答案

我有一个 ProgressableStreamContent 的工作版本。请注意,我在构造函数中添加 header ,这是原始 ProgressStreamContent 中的错误,它不添加 header !!

internal class ProgressableStreamContent : HttpContent
{

/// <summary>
/// Lets keep buffer of 20kb
/// </summary>
private const int defaultBufferSize = 5*4096;

private HttpContent content;
private int bufferSize;
//private bool contentConsumed;
private Action<long,long> progress;

public ProgressableStreamContent(HttpContent content, Action<long,long> progress) : this(content, defaultBufferSize, progress) { }

public ProgressableStreamContent(HttpContent content, int bufferSize, Action<long,long> progress)
{
if (content == null)
{
throw new ArgumentNullException("content");
}
if (bufferSize <= 0)
{
throw new ArgumentOutOfRangeException("bufferSize");
}

this.content = content;
this.bufferSize = bufferSize;
this.progress = progress;

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

protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
{

return Task.Run(async () =>
{
var buffer = new Byte[this.bufferSize];
long size;
TryComputeLength(out size);
var uploaded = 0;


using (var sinput = await content.ReadAsStreamAsync())
{
while (true)
{
var length = sinput.Read(buffer, 0, buffer.Length);
if (length <= 0) break;

//downloader.Uploaded = uploaded += length;
uploaded += length;
progress?.Invoke(uploaded, size);

//System.Diagnostics.Debug.WriteLine($"Bytes sent {uploaded} of {size}");

stream.Write(buffer, 0, length);
stream.Flush();
}
}
stream.Flush();
});
}

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);
}

}

另请注意,它需要 HttpContent,而不是流。

这是您可以使用它的方式。

 var progressContent = new ProgressableStreamContent (
requestContent,
4096,
(sent,total) => {
Console.WriteLine ("Uploading {0}/{1}", sent, total);
});

关于C#:HttpClient,将多个文件作为 MultipartFormDataContent 上传时的文件上传进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41378457/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com