PostAsJsonAsync doesnt seem to post body parameters
Asked Answered
S

3

11

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?

Stonechat answered 14/12, 2017 at 15:9 Comment(4)
have you called the json serializer you are using to verify the json is getting serialized correctly? looks like you are using SSL in the postman request, but not in your code. Also what's with the chunked encoding.Cyrie
looks similar to this question #35464733 Have you tried posting it without the PostAsJsonAsync extension method?Cyrie
I'm not sure what's with the chunked encoding. As you can see from my C# code, I'm not doing much except just calling PostJsonAsAsync and passing in my objectStonechat
So have you tried it without PostAsJsonAsync. ie. serializing the object and setting up all the headers by hand?Cyrie
O
12

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);
    }
Obara answered 2/2, 2018 at 13:7 Comment(2)
Where MimeTypes.Json are defined on?Information
@DanielSantos it could well be a static string for ( "application/json") that I added but not 100% sure.Obara
E
0

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);
Emblaze answered 14/12, 2017 at 23:28 Comment(0)
S
0

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

    }
}
Sepia answered 26/4, 2021 at 16:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.