JSON Object and Simple Type to Model in WebAPI using FromBody

14,357

Solution 1

The current JSON you are sending maps to the following classes

public class LoginData {
    public string UserName { get; set; }
    public string PasswordHash { get; set; }
    public string Nonce { get; set; }
    public string Language { get; set; }
    public bool SaveCredentials { get; set; }
}

public class UpdateModel {
    public LoginData oldCredentials { get; set; }
    public string newPassword { get; set; }
}

[FromBody] can only be used once in action parameters

[HttpPut("WebServices/UsersService.svc/rest/users/user")]
public void UpdatePassword([FromBody]UpdateModel model) {
    LoginData oldCredentials = model.oldCredentials;
    string newPassword = model.newPassword;
    NonceService.ValidateNonce(oldCredentials.Nonce);

    var users = UserStore.Load();
    var theUser = GetUser(oldCredentials.UserName, users);

    if (!UserStore.AuthenticateUser(oldCredentials, theUser)) {
        FailIncorrectPassword();
    }

    var iv = Encoder.GetRandomNumber(16);
    theUser.EncryptedPassword = Encoder.Encrypt(newPassword, iv);
    theUser.InitializationVektor = iv;

    UserStore.Save(users);
}

Solution 2

More than one [FromBody] does not work in Api. Check this Microsoft Official blog

So now you can do like this, create a complex object which should contain both your oldCredentials and newPassword. For example LoginData class in my example bellow. And myLoginRequest is another object class which is to deserialized your LoginData.

[HttpPut("UpdatePassword")]
[Route("WebServices/UsersService.svc/rest/users/user")]
public void UpdatePassword([FromBody]LoginData MyCredentials)
{
 loginRequest request = JsonConvert.DeserializeObject<myLoginRequest>
                            (json.ToString());

 // then you can do the rest

Solution 3

As per the Parameter Binding in ASP.NET Web API, "At most one parameter is allowed to read from the message body". Means only one parameter can contain [FromBody]. So in this case it will not work. Create one complex object and add required properties to it. You can add newPassword to your complex object to make it work.

Share:
14,357
Kingpin
Author by

Kingpin

I'm a software engineer at ise gmbh in Oldenburg

Updated on June 06, 2022

Comments

  • Kingpin
    Kingpin almost 2 years

    I am creating a Web Api method that should accept a JSON Object and a Simple Type. But all parameters are always null.

    My json looks like

    {
    "oldCredentials" : {
        "UserName" : "user",
        "PasswordHash" : "myCHqkiIAnybMPLzz3pg+GLQ8kM=",
        "Nonce" : "/SeVX599/KjPX/J+JvX3/xE/44g=",
        "Language" : null,
        "SaveCredentials" : false
    },
    "newPassword" : "asdf"}
    

    And my Code looks like:

    [HttpPut("UpdatePassword")]
    [Route("WebServices/UsersService.svc/rest/users/user")]
    public void UpdatePassword([FromBody]LoginData oldCredentials, [FromBody]string newPassword)
    {
      NonceService.ValidateNonce(oldCredentials.Nonce);
    
      var users = UserStore.Load();
      var theUser = GetUser(oldCredentials.UserName, users);
    
      if (!UserStore.AuthenticateUser(oldCredentials, theUser))
      {
        FailIncorrectPassword();
      }
    
      var iv = Encoder.GetRandomNumber(16);
      theUser.EncryptedPassword = Encoder.Encrypt(newPassword, iv);
      theUser.InitializationVektor = iv;
    
      UserStore.Save(users);
    }