在 WindowsPhone8中如何在 HttpClient 请求中发送 Post 主体?

我已经写了下面的代码发送标题,后参数。问题是我使用的是 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();
291435 次浏览

UPDATE 2:

From @Craig Brown:

As of .NET 5 you can do:
requestMessage.Content = JsonContent.Create(new { Name = "John Doe", Age = 33 });

See JsonContent class documentation

UPDATE 1:

Oh, it can be even nicer (from this answer):

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

This depends on what content do you have. You need to initialize your requestMessage.Content property with new HttpContent. For example:

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

where content is your encoded content. You also should include correct Content-type header.

I implemented it in the following way. I wanted a generic MakeRequest method that could call my API and receive content for the body of the request - and also deserialise the response into the desired type. I create a Dictionary<string, string> object to house the content to be submitted, and then set the HttpRequestMessage Content property with it:

Generic method to call the 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}");
}
}
}

Call the method:

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

I did create a method:

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 : Use StringContent in HttpContent, the inheritance is StringContent -> ByteArrayContent -> HttpContent.