C# .NET 中的异步 POST 请求

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15706736/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 17:40:32  来源:igfitidea点击:

Async POST request in C# .NET

c#postasynchronousrequesthttpclient

提问by MagiKruiser

I'm trying to upload a data over network using HttpClient / HttpContent However I can't seem to find a proper way to send a file this way.

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

Here is my current code:

这是我当前的代码:

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

Content is a string of that form: paramname=value&param2name=value&param3name=value.. Point is that I have to actually send a file (photo) over this request.

内容是这种形式的字符串:paramname=value¶m2name=value¶m3name=value.. 重点是我必须通过这个请求实际发送一个文件(照片)。

It seems to work fine for each parameters but the file itself (I have to send two authentification keys in the post request, and they are recognized)

它似乎适用于每个参数但文件本身(我必须​​在发布请求中发送两个身份验证密钥,并且它们被识别)

I proceed this way to retreive the picture as a string which might be one of the main reason it fails ? :/

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

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

Am I doing anything wrong ? Is there another and better way to create a proper POST request (it has to be async and support file upload)

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

Thanks.

谢谢。

采纳答案by MagiKruiser

Main problem was probably coming from the fact i was mixing string and file data.

主要问题可能是因为我混合了字符串和文件数据。

This solved it:

这解决了它:

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

Mainly using Multipart Content, setting the Content Type and going through a byte array seem to have done the job.

主要使用多部分内容,设置内容类型并通过字节数组似乎已经完成了这项工作。

回答by carlosfigueira

Do you need to send the data as a base64-encoded string? If you're sending arbitrary bytes (i.e., a photo), you can send them unencoded, if you use the ByteArrayContentclass:

您是否需要将数据作为 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);
}