【问题标题】:How to send a Post body in the HttpClient request in Windows Phone 8?如何在 Windows Phone 8 的 HttpClient 请求中发送 Post 正文?
【发布时间】:2014-09-29 06:35:13
【问题描述】:

我已经编写了下面的代码来发送标题,发布参数。问题是我使用的是 SendAsync,因为我的请求可以是 GET 或 POST。如何将 POST Body 添加到这段代码中,以便如果有任何 post body 数据,它会被添加到我发出的请求中,并且如果它的简单 GET 或 POST 没有 body,它会以这种方式发送请求。请更新以下代码:

HttpClient client = new HttpClient();

// Add a new Request Message
HttpRequestMessage requestMessage = new HttpRequestMessage(RequestHTTPMethod, ToString());

// Add our custom headers
if (RequestHeader != null)
{
    foreach (var item in RequestHeader)
    {

        requestMessage.Headers.Add(item.Key, item.Value);

    }
}

// Add request body


// Send the request to the server
HttpResponseMessage response = await client.SendAsync(requestMessage);

// Get the response
responseString = await response.Content.ReadAsStringAsync();

【问题讨论】:

  • 请查看更新后的答案,它有更好的方法。

标签: c# windows-phone-8 httpclient


【解决方案1】:

我确实创建了一个方法:

public static StringContent GetBodyJson(params (string key, string value)[] param)
    {
        if (param.Length == 0)
            return null;

        StringBuilder builder = new StringBuilder();

        builder.Append(" { ");

        foreach((string key, string value) in param)
        {
            builder.Append(" \"" + key + "\" :"); // key
            builder.Append(" \"" + value + "\" ,"); // value
        }

        builder.Append(" } ");

        return new StringContent(builder.ToString(), Encoding.UTF8, "application/json");
    }

obs : 在HttpContent中使用StringContent,继承是StringContent -> ByteArrayContent -> HttpContent。

【讨论】:

    【解决方案2】:

    更新 2:

    来自@Craig Brown

    从 .NET 5 开始,您可以这样做:
    requestMessage.Content = JsonContent.Create(new { Name = "John Doe", Age = 33 });

    参见JsonContent 类文档

    更新 1:

    哦,它可以更好(来自answer):

    requestMessage.Content = new StringContent("{\"name\":\"John Doe\",\"age\":33}", Encoding.UTF8, "application/json");
    

    这取决于你有什么内容。您需要使用新的HttpContent 初始化您的requestMessage.Content 属性。例如:

    ...
    // Add request body
    if (isPostRequest)
    {
        requestMessage.Content = new ByteArrayContent(content);
    }
    ...
    

    content 是您的编码内容。您还应该包含正确的 Content-type 标头。

    【讨论】:

    • 如何使用 jsonSerializer 将 Json 写入内容?
    • @GiriB 我使用 Newtonsoft.Json 包这样做:requestMessage.Content = new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json"); 您也可以使用 JsonSerializer 像您当前正在做的那样序列化为字符串,然后将该字符串传递为StringContent 构造函数的第一个参数。
    • 从 .NET 5 开始,您可以这样做:requestMessage.Content = JsonContent.Create(new {Name = "John Doe", Age = 33});
    【解决方案3】:

    我通过以下方式实现它。我想要一个通用的 MakeRequest 方法,它可以调用我的 API 并接收请求正文的内容 - 并将响应反序列化为所需的类型。我创建了一个Dictionary<string, string> 对象来存放要提交的内容,然后用它设置HttpRequestMessage Content 属性:

    调用 API 的通用方法:

        private static T MakeRequest<T>(string httpMethod, string route, Dictionary<string, string> postParams = null)
        {
            using (var client = new HttpClient())
            {
                HttpRequestMessage requestMessage = new HttpRequestMessage(new HttpMethod(httpMethod), $"{_apiBaseUri}/{route}");
    
                if (postParams != null)
                    requestMessage.Content = new FormUrlEncodedContent(postParams);   // This is where your content gets added to the request body
    
    
                HttpResponseMessage response = client.SendAsync(requestMessage).Result;
    
                string apiResponse = response.Content.ReadAsStringAsync().Result;
                try
                {
                    // Attempt to deserialise the reponse to the desired type, otherwise throw an expetion with the response from the api.
                    if (apiResponse != "")
                        return JsonConvert.DeserializeObject<T>(apiResponse);
                    else
                        throw new Exception();
                }
                catch (Exception ex)
                {
                    throw new Exception($"An error ocurred while calling the API. It responded with the following message: {response.StatusCode} {response.ReasonPhrase}");
                }
            }
        }
    

    调用方法:

        public static CardInformation ValidateCard(string cardNumber, string country = "CAN")
        { 
            // Here you create your parameters to be added to the request content
            var postParams = new Dictionary<string, string> { { "cardNumber", cardNumber }, { "country", country } };
            // make a POST request to the "cards" endpoint and pass in the parameters
            return MakeRequest<CardInformation>("POST", "cards", postParams);
        }
    

    【讨论】:

    • 这个实现的几个问题。首先,它不是异步的。使用“.Result”会导致这是一个阻塞调用。第二个问题是它不能扩展!在这里查看我的答案 - stackoverflow.com/questions/22560971/… 第三个问题是您正在抛出异常来处理控制流。这不是一个好习惯。见 - docs.microsoft.com/en-us/visualstudio/profiling/…
    • 感谢您的意见。我会检查这些链接
    • @AdamHey 非常适合同步请求,谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-27
    • 2016-11-03
    • 1970-01-01
    • 2019-08-25
    相关资源
    最近更新 更多