如何在Windows Phone 8中的HttpClient请求中发送帖子正文?

Bal*_*ngh 43 c# httpclient windows-phone-8

我已经编写了下面的代码来发送标题,发布参数.问题是我使用SendAsync,因为我的请求可以是GET或POST.如何将POST Body添加到此代码中,以便如果有任何帖子正文数据,则会在我发出的请求中添加它,如果它的简单GET或POST没有正文,则会以此方式发送请求.请更新以下代码:

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();
Run Code Online (Sandbox Code Playgroud)

Ily*_*nin 99

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

...
// Add request body
if (isPostRequest)
{
    requestMessage.Content = new ByteArrayContent(content);
}
...
Run Code Online (Sandbox Code Playgroud)

content你的编码内容在哪里.您还应该包含正确的Content-type标头.

更新:

哦,它可以更好(从这个答案):

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

  • @GiriB我使用Newtonsoft.Json包这样做:`requestMessage.Content = new StringContent(JsonConvert.SerializeObject(body),Encoding.UTF8,"application/json");`你也可以使用JsonSerializer来序列化您可能正在进行的字符串,然后将该字符串作为第一个参数传递给StringContent构造函数. (3认同)
  • 从 .NET 5 开始,您可以执行以下操作: `requestMessage.Content = JsonContent.Create(new {Name = "John Doe", Age = 33});` (3认同)

Ada*_*Hey 5

我用以下方式实现它.我想要一个通用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}");
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

调用方法:

    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);
    }
Run Code Online (Sandbox Code Playgroud)

  • 这个实现有几个问题。首先,它不是异步的。使用“.Result”导致这是一个阻塞调用。第二个问题是它不缩放!在这里查看我的答案 - /sf/ask/1579268001/ #35045301 第三个问题是您抛出异常来处理控制流。这不是一个好的做法。请参阅 - https://docs.microsoft.com/en-us/visualstudio/profiling/da0007-avoid-using-exceptions-for-control-flow?view=vs-2019 (4认同)
  • 另外,你还有内存泄漏。`HttpRequestMessage` 实现了 `IDisposable`,所以你需要将它包装在 `using` 中 (2认同)