C# Xamarin 文件上传到 API 可以使用 RestSharp 但不能使用 HttpClient
C# Xamarin file upload to API works using RestSharp but does not work using HttpClient
我正在尝试从我的 Xamarin 应用程序将图像文件从 phone 相机上传到 BuddyPress API(可以在此处找到 API 调用文档 - https://developer.buddypress.org/bp-rest-api/reference/attachments/member-avatar/)
我可以使用 RestSharp 成功完成此操作,如下所示;
public string PostMediaFile(MediaFile data, string path, bool https = false, string authorisationToken = "")
{
var requestMethod = "http://";
if (https)
{
requestMethod = "https://";
}
var serverString = requestMethod + path;
var client = new RestClient(serverString)
{
Timeout = Convert.ToInt32(timeOut)
};
client.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer " + authorisationToken);
request.AddHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36");
request.AddFile("file", data.Path);
request.AddParameter("action", "bp_avatar_upload");
IRestResponse response = client.Execute(request);
return response.Content;
}
但是,我在应用程序中的所有其他请求都是使用 HttpClient 执行的,我想保持一致,所以我想出了以下函数来替换它;
public async Task<string> PostMediaFile(MediaFile data, string path, bool https = false, string authorisationToken = "")
{
var memoryStream = new MemoryStream();
data.GetStream().CopyTo(memoryStream);
byte[] fileAsBytes = memoryStream.ToArray();
var fileContent = new ByteArrayContent(fileAsBytes);
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
Name = "file",
FileName = Path.GetFileName(data.Path),
};
fileContent.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
var content = new MultipartFormDataContent
{
{ fileContent, "file", Path.GetFileName(data.Path) },
{ new StringContent("action"), "bp_avatar_upload" }
};
var requestMethod = "http://";
if (https)
{
requestMethod = "https://";
}
var clientHandler = new HttpClientHandler()
{
ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; }
};
httpClient = new HttpClient(clientHandler);
if (!string.IsNullOrWhiteSpace(authorisationToken))
{
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authorisationToken);
httpClient.DefaultRequestHeaders.UserAgent.TryParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36");
}
httpClient.Timeout = TimeSpan.FromMilliseconds(timeOut);
var serverString = requestMethod + path;
HttpResponseMessage response = await httpClient.PostAsync(serverString, content);
HttpContent Content = response.Content;
var json = await Content.ReadAsStringAsync();
response.Dispose();
return json;
}
问题是,明明是行不通的,我也不知道为什么。我刚收到以下回复;
{"code":"bp_rest_attachments_user_avatar_upload_error","message":"Upload failed! Error was: Invalid form submission..","data":{"status":500,"reason":"upload_error"}}
我觉得我真的很接近,但不确定我的错误在哪里。
啊!太简单了!我有部分表格数据弄错了;
{ new StringContent("action"), "bp_avatar_upload" }
应该是
{ new StringContent("bp_avatar_upload"), "action" }
我正在尝试从我的 Xamarin 应用程序将图像文件从 phone 相机上传到 BuddyPress API(可以在此处找到 API 调用文档 - https://developer.buddypress.org/bp-rest-api/reference/attachments/member-avatar/)
我可以使用 RestSharp 成功完成此操作,如下所示;
public string PostMediaFile(MediaFile data, string path, bool https = false, string authorisationToken = "")
{
var requestMethod = "http://";
if (https)
{
requestMethod = "https://";
}
var serverString = requestMethod + path;
var client = new RestClient(serverString)
{
Timeout = Convert.ToInt32(timeOut)
};
client.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer " + authorisationToken);
request.AddHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36");
request.AddFile("file", data.Path);
request.AddParameter("action", "bp_avatar_upload");
IRestResponse response = client.Execute(request);
return response.Content;
}
但是,我在应用程序中的所有其他请求都是使用 HttpClient 执行的,我想保持一致,所以我想出了以下函数来替换它;
public async Task<string> PostMediaFile(MediaFile data, string path, bool https = false, string authorisationToken = "")
{
var memoryStream = new MemoryStream();
data.GetStream().CopyTo(memoryStream);
byte[] fileAsBytes = memoryStream.ToArray();
var fileContent = new ByteArrayContent(fileAsBytes);
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
Name = "file",
FileName = Path.GetFileName(data.Path),
};
fileContent.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
var content = new MultipartFormDataContent
{
{ fileContent, "file", Path.GetFileName(data.Path) },
{ new StringContent("action"), "bp_avatar_upload" }
};
var requestMethod = "http://";
if (https)
{
requestMethod = "https://";
}
var clientHandler = new HttpClientHandler()
{
ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; }
};
httpClient = new HttpClient(clientHandler);
if (!string.IsNullOrWhiteSpace(authorisationToken))
{
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authorisationToken);
httpClient.DefaultRequestHeaders.UserAgent.TryParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36");
}
httpClient.Timeout = TimeSpan.FromMilliseconds(timeOut);
var serverString = requestMethod + path;
HttpResponseMessage response = await httpClient.PostAsync(serverString, content);
HttpContent Content = response.Content;
var json = await Content.ReadAsStringAsync();
response.Dispose();
return json;
}
问题是,明明是行不通的,我也不知道为什么。我刚收到以下回复;
{"code":"bp_rest_attachments_user_avatar_upload_error","message":"Upload failed! Error was: Invalid form submission..","data":{"status":500,"reason":"upload_error"}}
我觉得我真的很接近,但不确定我的错误在哪里。
啊!太简单了!我有部分表格数据弄错了;
{ new StringContent("action"), "bp_avatar_upload" }
应该是
{ new StringContent("bp_avatar_upload"), "action" }