ASP.NET Core API POST parameter is always null

ridiculously, in dot net core you cannot use just "frombody string parameter". you should make a model class for just one string parameter.

public async Task<IActionResult> GetRankings([FromBody] string cookie)

=>

//1. make a model. MyCookie.cs
class MyCookie{
   public string Cookie { get; set; }
}
//2. edit your parameter
public async Task<IActionResult> GetRankings([FromBody] MyCookie cookie)

Shaun Luttin's answer works, but it misses one important piece of information. The reason your string is not recognised is because it is not a JSON string.

Do this;

var payload=JSON.stringify("=sec_session_id=[redacted]; _ga=[redacted]; AWSELB=[redacted]");

Then you can leave the controller as it is;

$.ajax({
    url: http://localhost:54093/getter/validatecookie,
    type: 'POST',
    contentType: 'application/json',
    data: payload
});

It is embarassing how long this took me to figure out. I really hope it helps someone!


The problem is that the Content-Type is application/json, whereas the request payload is actually text/plain. That will cause a 415 Unsupported Media Type HTTP error.

You have at least two options to align then Content-Type and the actual content.

Use application/json

Keep the Content-Type as application/json and make sure the request payload is valid JSON. For instance, make your request payload this:

{
    "cookie": "=sec_session_id=[redacted]; _ga=[redacted]; AWSELB=[redacted]"
} 

Then the action signature needs to accept an object with the same shape as the JSON object.

public class CookieWrapper
{
    public string Cookie { get; set; }
}

Instead of the CookieWrapper class, or you can accept dynamic, or a Dictionary<string, string> and access it like cookie["cookie"] in the endpoint

public IActionResult GetRankings([FromBody] CookieWrapper cookie)

public IActionResult GetRankings([FromBody] dynamic cookie)

public IActionResult GetRankings([FromBody] Dictionary<string, string> cookie)

Use text/plain

The other alternative is to change your Content-Type to text/plain and to add a plain text input formatter to your project. To do that, create the following class.

public class TextPlainInputFormatter : TextInputFormatter
{
    public TextPlainInputFormatter()
    {
        SupportedMediaTypes.Add("text/plain");
        SupportedEncodings.Add(UTF8EncodingWithoutBOM);
        SupportedEncodings.Add(UTF16EncodingLittleEndian);
    }

    protected override bool CanReadType(Type type)
    {
        return type == typeof(string);
    }

    public override async Task<InputFormatterResult> ReadRequestBodyAsync(
        InputFormatterContext context, 
        Encoding encoding)
    {
        string data = null;
        using (var streamReader = context.ReaderFactory(
            context.HttpContext.Request.Body, 
            encoding))
        {
            data = await streamReader.ReadToEndAsync();
        }

        return InputFormatterResult.Success(data);
    }
}

And configure Mvc to use it.

services.AddMvc(options =>
{
    options.InputFormatters.Add(new TextPlainInputFormatter());
});

See also

https://github.com/aspnet/Mvc/issues/5137