Jack Shepherd
Jack Shepherd

Reputation: 393

PostAsJsonAsync doesnt seem to post body parameters

I have created an Azure logic app that exposes a REST endpoint.

The following JSON body works fine when I call it through postman.

{
   "to": "[email protected]",
   "subject": "Hello there",
   "message": "Hello there!!!!!"
}

I'm able to see the incoming request formed nicely

{
    "headers": {
        "Cache-Control": "no-cache",
        "Connection": "keep-alive",
        "Accept": "*/*",
        "Accept-Encoding": "gzip,deflate",
        "Host": "maskedout.northcentralus.logic.azure.com:443",
        "User-Agent": "PostmanRuntime/6.4.1",
        "Content-Length": "99",
        "Content-Type": "application/json"
    },
    "body": {
        "to": "[email protected]",
        "subject": "Hello there",
        "message": "Hello there!!!!!"
    }
}

However, when I try to make the same call using C# PostAsJsonAsync with this code:

        var email = new Email
        {
            to = "[email protected]",
            subject = "from webapp",
            message = "hello world"
        };
        var client = new HttpClient();
        var uri = "maskedout";
        var response = await client.PostAsJsonAsync<Email>(uri, email);

I'm able to call my REST endpoint successfully, but it does not contain the body

This is the incoming request I see:

{
    "headers": {
        "Connection": "Keep-Alive",
        "Transfer-Encoding": "chunked",
        "Host": "maskedout.northcentralus.logic.azure.com",
        "x-ms-request-root-id": "9e5513c2-43961642a3688718",
        "x-ms-request-id": "|9e5513c2-43961642a3688718.1.",
        "Request-Id": "|9e5513c2-43961642a3688718.1.1.",
        "Content-Type": "application/json; charset=utf-8",
        "Content-Length": "0"
    }
}

What am I missing here? What's different in my C# code compared to postman?

Upvotes: 12

Views: 8940

Answers (3)

gius
gius

Reputation: 9437

I just had the same problem. It seems that the content-length header is set to 0 when using the default PostAsJsonAsync extension method, which causes the server to ignore the request body.

My solution was to install the System.Net.Http.Json nuget package that uses the new System.Text.Json serializer.

When you add using System.Net.Http.Json;, you should be able to use the new extension method PostAsJsonAsync that works (sets the content-length header) properly.

namespace System.Net.Http.Json
{
    public static class HttpClientJsonExtensions
    {
        public static Task<HttpResponseMessage> PostAsJsonAsync<TValue>(this HttpClient client, string? requestUri, TValue value, CancellationToken cancellationToken)
        {
            return client.PostAsJsonAsync(requestUri, value, null, cancellationToken);
        }

    }
}

Upvotes: 0

James Mundy
James Mundy

Reputation: 4329

I've just run into this problem too. The issue appears to be the Content-Length header. In Postman it is the length of the content but using HttpClient the length is 0 so I am guessing the endpoint is ignoring the body as it is being told it is empty.

I created my own extension to get around this:

public static async Task<HttpResponseMessage> PostJsonAsync<T>(
        this HttpClient client,
        string requestUri,
        T value)
    {
        var data = JsonConvert.SerializeObject(value);
        var content = new StringContent(data,
                                        Encoding.UTF8,
                                        MimeTypes.Json);
        Debug.WriteLine(client.BaseAddress + requestUri);
        return await client.PostAsync(requestUri,
                                      content)
                           .WithRequestTimeout()
                           .ConfigureAwait(false);
    }

Upvotes: 12

Paco de la Cruz
Paco de la Cruz

Reputation: 2154

the TransferEncodingChunked header property should be false by default.

However, try this:

        var email = new Email
        {
            to = "[email protected]",
            subject = "from webapp",
            message = "hello world"
        };
        var client = new HttpClient();
        var uri = "maskedout";
        client.DefaultRequestHeaders.TransferEncodingChunked = false;
        var response = await client.PostAsJsonAsync<Email>(uri, email);

Upvotes: 0

Related Questions