Geekn
Geekn

Reputation: 2882

StringContent results in null value but FormUrlEncodedContent works correctly

I have the following model in an ASP.NET Core 2.0 Web API

public class LoginModel
{
    public string Username { get; set; }
    public string Password { get; set; }
}

Which contains the following action

[HttpPost]
public async Task<IActionResult> Login(LoginModel model)
{
    if (ModelState.IsValid)
    {
        var result = await SignInManager.PasswordSignInAsync(model.Username, model.Password, false, false);
        if (result.Succeeded)
        {
            ApplicationUser user = await UserManager.FindByNameAsync(model.Username);
            return new ObjectResult(await GenerateToken(user));
        }
    }
    return BadRequest(model);
}

When using StringContent with JsonConvert in a test client this results in NULL values showing up in the model when posted to the action on the controller.

var credentials = new LoginModel() { Username = "[email protected]", Password = "somePassword" };
var content = new StringContent(JsonConvert.SerializeObject(credentials), Encoding.UTF8, "application/json");        
var response = await client.PostAsync("/api/auth/login", content);

When using FormUrlEncodedContent, the model is populated correctly in the action on the controller.

var content = new FormUrlEncodedContent(new[]
{
     new KeyValuePair<string, string>("username", "[email protected]"),
     new KeyValuePair<string, string>("password", "somePassword"),
}
var response = await client.PostAsync("/api/auth/login", content);

I've also tried using the HttpClient extensions which also results in no values showing up in the model when posted.

var credentials = new LoginModel() { Username = "[email protected]", Password = "somePassword" };
var response = await client.PostAsJsonAsync<LoginModel>("/api/auth/login", credentials);

What am I missing? Any help would be greatly appreciated.

Upvotes: 1

Views: 2952

Answers (1)

Nkosi
Nkosi

Reputation: 247333

Update action to look for the content in the request body using [FromBody] attribute

[HttpPost]
public async Task<IActionResult> Login([FromBody]LoginModel model) {
    //...code removed for brevity
}

Reference Asp.Net Core: Model Binding

Upvotes: 1

Related Questions