【发布时间】:2016-12-29 11:07:02
【问题描述】:
我正在使用此代码上传多个文件,并且运行良好。它使用现代的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;
}
}
我应该怎么做才能让它工作?任何帮助表示赞赏
【问题讨论】:
-
你必须使用 MultiPartContent,而不是 ByteArrayContent
-
我将文件作为字节数组。
-
服务器不接受字节数组,http服务器大多需要多部分形式编码的内容,这是服务器期望数据的方式,而不是您发送的方式
-
我将每个 ByteArrayContent 添加到 MultipartFormDataContent。请查看代码,它就像我在文章开头所说的那样工作。
标签: c# file-upload xamarin httpclient multipartform-data