【问题标题】:Async POST request in C# .NETC# .NET 中的异步 POST 请求
【发布时间】:2026-01-28 02:00:01
【问题描述】:

我正在尝试使用 HttpClient / HttpContent 通过网络上传数据 但是我似乎找不到以这种方式发送文件的正确方法。

这是我当前的代码:

    private async Task<APIResponse> MakePostRequest(string RequestUrl, string Content)
    {
        HttpClient  httpClient = new HttpClient();
        HttpContent httpContent = new StringContent(Content);
        APIResponse serverReply = new APIResponse();

        httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        try {
            Console.WriteLine("Sending Request: " + RequestUrl + Content);
            HttpResponseMessage response = await httpClient.PostAsync(RequestUrl, httpContent).ConfigureAwait(false);
        }
        catch (HttpRequestException hre)
        {
            Console.WriteLine("hre.Message");
        }
        return (serverReply);
    }

内容是这种形式的字符串:paramname=value&param2name=value&param3name=value.. 关键是我必须通过这个请求实际发送一个文件(照片)。

似乎每个参数都可以正常工作,但文件本身(我必须​​在发布请求中发送两个身份验证密钥,并且它们被识别)

我以这种方式将图片作为字符串检索,这可能是它失败的主要原因之一? :/

    byte[] PictureData = File.ReadAllBytes(good_path);
    string encoded = Convert.ToBase64String(PictureData);

我做错了吗?是否有另一种更好的方法来创建正确的 POST 请求(它必须是异步的并支持文件上传)

谢谢。

【问题讨论】:

    标签: c# post asynchronous request httpclient


    【解决方案1】:

    主要问题可能来自我混合字符串和文件数据的事实。

    这解决了它:

        public async Task<bool> CreateNewData (Data nData)
        {
            APIResponse serverReply;
    
            MultipartFormDataContent form = new MultipartFormDataContent ();
    
            form.Add (new StringContent (_partnerKey), "partnerKey");
            form.Add (new StringContent (UserData.Instance.key), "key");
            form.Add (new StringContent (nData.ToJson ()), "erList");
    
            if (nData._FileLocation != null) {
                string good_path = nData._FileLocation.Substring (7); // Dangerous
                byte[] PictureData = File.ReadAllBytes (good_path);
                HttpContent content = new ByteArrayContent (PictureData);
                content.Headers.Add ("Content-Type", "image/jpeg");
                form.Add (content, "picture_0", "picture_0");
            }
    
            form.Add (new StringContent (((int)(DateTime.Now.ToUniversalTime () -
                new DateTime (1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds).ToString ()), "time");
            serverReply = await MakePostRequest (_baseURL + "Data-report/create", form);
    
            if (serverReply.Status == SERVER_OK)
                return (true);
            Android.Util.Log.Error ("MyApplication", serverReply.Response);
            return (false);
        }
    
        private async Task<APIResponse> MakePostRequest (string RequestUrl, MultipartFormDataContent Content)
        {
            HttpClient httpClient = new HttpClient ();
            APIResponse serverReply = new APIResponse ();
    
            try {
                Console.WriteLine ("MyApplication - Sending Request");
                Android.Util.Log.Info ("MyApplication", " Sending Request");
                HttpResponseMessage response = await httpClient.PostAsync (RequestUrl, Content).ConfigureAwait (false);
                serverReply.Status = (int)response.StatusCode;
                serverReply.Response = await response.Content.ReadAsStringAsync ();
            } catch (HttpRequestException hre) {
                Android.Util.Log.Error ("MyApplication", hre.Message);
            }
            return (serverReply);
        }
    

    主要使用Multipart Content,设置Content Type并通过字节数组似乎已经完成了这项工作。

    【讨论】:

      【解决方案2】:

      您需要将数据作为 base64 编码的字符串发送吗?如果您要发送任意字节(即照片),则可以发送未编码的字节,如果您使用 ByteArrayContent 类:

      private async Task<APIResponse> MakePostRequest(string RequestUrl, byte[] Content)
      {
          HttpClient  httpClient = new HttpClient();
          HttpContent httpContent = new ByteArrayContent(Content);
          APIResponse serverReply = new APIResponse();
      
          try {
              Console.WriteLine("Sending Request: " + RequestUrl + Content);
              HttpResponseMessage response = await httpClient.PostAsync(RequestUrl, httpContent).ConfigureAwait(false);
              // do something with the response, like setting properties on serverReply?
          }
          catch (HttpRequestException hre)
          {
              Console.WriteLine("hre.Message");
          }
      
          return (serverReply);
      }
      

      【讨论】:

      • 我在同一个请求中发送一个字符串、JSON 数组和照片。这有关系吗?也不要担心响应,我确实设置了它,我只是从代码中删除了部分,因为它并不真正相关。
      • 是的,这很重要。服务器如何期望字符串和数组参数?作为 HTTP 标头,作为正文的一部分,还有其他方式吗?客户端必须以服务器期望的方式发送请求。