C# Xamarin 文件上传到 API 可以使用 RestSharp,但不能使用 HttpClient

Posted

技术标签:

【中文标题】C# Xamarin 文件上传到 API 可以使用 RestSharp,但不能使用 HttpClient【英文标题】:C# Xamarin file upload to API works using RestSharp but does not work using HttpClient 【发布时间】:2021-10-21 11:43:42 【问题描述】:

我正在尝试从我的 Xamarin 应用程序将图像文件从手机摄像头上传到 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"

我觉得我真的很接近,但不确定我的错误在哪里。

【问题讨论】:

您能在 BuddyPress 中捕获请求并进行比较吗? 感谢 Jason 的提示,我找到了问题所在! 【参考方案1】:

啊!就是这么简单!我弄错了部分表单数据;

 new StringContent("action"), "bp_avatar_upload" 

应该是

 new StringContent("bp_avatar_upload"), "action" 

【讨论】:

以上是关于C# Xamarin 文件上传到 API 可以使用 RestSharp,但不能使用 HttpClient的主要内容,如果未能解决你的问题,请参考以下文章

使用 C# 和 Xamarin 调用 API 和获取数据

使用 Angular 6 将文件上传到 Web Api C#

如何在 C# 中正确使用 WCF REST API 上的 Stream 将文件(图像/视频/等)上传到服务器?

如何使用 Xamarin 表单和 C# 将 Html 数据从网站保存到文本文件

将android java转换为xamarin c#

上传 UIImage 类型的图像列表(Xamarin)