213

The API I'm trying to call requires a POST with an empty body. I'm using the WCF Web API HttpClient, and I can't find the right code that will post with an empty body. I found references to some HttpContent.CreateEmpty() method, but I don't think it’s for the Web API HttpClient code since I can't seem to find that method.

starball
  • 20,030
  • 7
  • 43
  • 238
Ryan Rinaldi
  • 4,119
  • 2
  • 22
  • 22
  • HttpContent.CreateEmpty was from the old HttpClient prototype that was part of REST Starter kit. Unfortunately there is no equivalent in the new HttpClient. – Darrel Miller Oct 27 '11 at 23:18
  • Possible duplicate of [How do I set up HttpContent for my HttpClient PostAsync second parameter?](https://stackoverflow.com/questions/18971510/how-do-i-set-up-httpcontent-for-my-httpclient-postasync-second-parameter) – Michael Freidgeim Apr 16 '18 at 02:25
  • 2
    @MichaelFreidgeim If there was a hole in the space time continuum and somehow 2013 came before 2011, then yes it is a possible duplicate. – Ryan Rinaldi Jun 19 '18 at 16:04
  • 2
    "Possible duplicate" is a way to clean-up - to close similar questions and keep one with the best answers. The date is not essential. See http://meta.stackexchange.com/questions/147643/should-i-vote-to-close-a-duplicate-question-even-though-its-much-newer-and-ha If you agree that it requires clarification please vote on http://meta.stackexchange.com/questions/281980/add-clarification-link-to-possible-duplicate-automated-comment – Michael Freidgeim Jun 19 '18 at 22:24

7 Answers7

268

Use StringContent or ObjectContent which derive from HttpContent or you can use null as HttpContent:

var response = await client.PostAsync(requestUri, null);
Soviut
  • 88,194
  • 49
  • 192
  • 260
Alexander Zeitler
  • 11,919
  • 11
  • 81
  • 124
  • It looks like this is only in .NET framework 4.5? http://msdn.microsoft.com/en-us/library/system.net.http.stringcontent(v=VS.110).aspx – dan Dec 28 '11 at 03:54
  • It will ship with WCF Web API but I think some of the "good parts" will make it into the framework itself. – Alexander Zeitler Dec 28 '11 at 07:33
  • 1
    Why isn't there any overload methods which does not require a `HttpContent` class? Should we at least provide something (even an empty string) to make a http post? – tugberk Jan 30 '12 at 10:28
  • 86
    You can use `null` as the `HttpContent`, this will send no body in the request, e.g. `var response = await client.PostAsync(requestUri, null);` – Owain Williams Aug 05 '15 at 13:09
  • @OwainWilliams said the same as the original answer, but this comment got way more upvotes as it's straight to the point, for me, boosted the confidence ;) – Deepak Jan 20 '21 at 16:25
  • 7
    Assembly `System.Net.Http` in version 5.0.0.0 has still no nullable `HttpContent` parameter, so `null` should be not allowed. But it (still) seems to work. I could pass `null!`. – Andi Feb 17 '21 at 17:36
  • C# 8.0 introduced [nullable reference types](https://learn.microsoft.com/en-us/dotnet/csharp/nullable-references), before that _all_ reference types could be `null`. I assume the public `HttpContent` parameters in the [`HttpClient`](https://github.com/dotnet/runtime/blob/v5.0.5/src/libraries/System.Net.Http/src/System/Net/Http/HttpClient.cs) have not been explicitly declared as non-nullable to maintain backwards compatibility with older C# versions. I can't see anything in the code that implies the `HttpContent` cannot be `null`, which I interpret to mean that `null` _**is**_ allowed. – Owain Williams Apr 26 '21 at 11:36
  • @OwainWilliams in case you do not want to use null there, feel free to call like that: httpClient.PostAsync(uri, new StringContent(String.Empty)). – Mikheil Zhghenti Jul 26 '22 at 15:04
  • for me I don't need to put a body, but need to add some header then use StringContent was ok, you can create a content with string.empty and put there the header that you want – freedeveloper Aug 03 '22 at 19:12
132

Did this before, just keep it simple:

Task<HttpResponseMessage> task = client.PostAsync(url, null);
Ogglas
  • 62,132
  • 37
  • 328
  • 418
11

Have found that:

Task<HttpResponseMessage> task = client.PostAsync(url, null);

Adds null to the request body, which failed on WSO2. Replaced with:

Task<HttpResponseMessage> task = client.PostAsync(url, new {});

And worked.

Erik Philips
  • 53,428
  • 11
  • 128
  • 150
Ryan Tuck
  • 121
  • 1
  • 3
  • I cannot confirm this finding (but I am not sure my test was totally adequate). When I POST to one of my own APIs with a `null` content and look at the content found in the `HttpRequestMessage`, I seem to be getting a length of zero bytes. – O. R. Mapper Nov 18 '19 at 12:03
3

In case you do not want to pass null value you can you the following:

Task<HttpResponseMessage> task = httpClient.PostAsync(uri, new StringContent(String.Empty));

But, beside this, as above already discussed you could pass null in there as a parameter.

Mikheil Zhghenti
  • 734
  • 8
  • 28
2

To solve this problem, use this example:

   using (var client = new HttpClient())
            {
                var stringContent = new StringContent(string.Empty);
                stringContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded");
                var response = client.PostAsync(url, stringContent).Result;
                var result = response.Content.ReadAsAsync<model>().Result;
            }
1

If you wish to avoid 'null' and make your intentions clear, as do I, you can override the StringContent class:

    private sealed class DeliberatelyEmptyContent : StringContent
    {
        public DeliberatelyEmptyContent() : base(string.Empty)
        {
        }
    }

    public async Task ActivateUser(string xflowUserId)
    {
        var httpclient = _httpClientFactory.CreateClient(_namedHttpClientName);
        string activateUrl = $"/User/{xflowUserId}/Activate";

        _ = await httpclient.PutAsync(activateUrl, new DeliberatelyEmptyContent());
    }
Morten Nørgaard
  • 2,609
  • 2
  • 24
  • 24
-6

I think it does that automagically if your web method has no parameters or they all fit into URL template.

For example this declaration sends empty body:

  [OperationContract]
  [WebGet(UriTemplate = "mykewlservice/{emailAddress}",
     RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json,
     BodyStyle = WebMessageBodyStyle.Wrapped)]
  void GetStatus(string emailAddress, out long statusMask);
Ivan G.
  • 5,027
  • 2
  • 37
  • 65
  • I'm trying to SEND an empty body. The HttpClient.Post() method requires an URI and a HttpContent object. I'm not what to pass as the HttpContent when I don't want to send anything. – Ryan Rinaldi Oct 26 '11 at 19:27
  • So you're not using WCF. That's even easier: ... HttpWebRequest request = (HttpWebRequest) WebRequest.Create("http://..."); request.Method = "POST"; HttpWebResponse respose = (HttpWebResponse)request.GetResponse(); ... you result in response – Ivan G. Oct 26 '11 at 19:30
  • 1
    I'm using HttpClient, not HttpWebRequest. Using StringContent with an empty string worked. – Ryan Rinaldi Oct 27 '11 at 16:11