POSTing data to ASP.NET WEB API Service from Node.js

I currently work on an app to allow my company's executives to perform certain actions from anywhere. My Node.js piece serves as a proxy between the Internet and my company's internal LAN and calls some ASP.NET WEB API services on the company LAN to handle Active Directory Authentication (so the execs can use their windows logon) and storing and retrieving data from SQL Server 2008.

The ASP.Net AuthenticateUser() function accepts an HTTP POST request containing the userId and pas and returns a JSON object containing a hash the client can use to sign requests. It works fine when I pass the userId & password as query parameters, but it fails when I try to embed them in the request body. The working version looks like the following. (NOTE: I omitted error handling to improve clarity.)

    namespace Approver.Controllers 
   {
      public class UtilityController : ApiController 
      {
        public UserInfo AuthenticateUser(string userId, string password) 
        {
          return UtilityBo.AuthenticateUser(userId, password); 
        } 
      } 
   }

The working Node.js code (i.e. a route in Express) looks like this.

exports.login = function(req, res){
var userId = req.body.userId;
var password = req.body.password;
var postData = 'userId='+userId+'&password='+password;
});
var options = {
  host: res.app.settings['serviceHost'],
  port: res.app.settings['servicePort'],
  path: '/api/Utility/AuthenticateUser?userId='+userId+'&password='+password,
  method: 'POST',
  header: {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Content-Length': postData.length
  }
};      
http.request(options, function(resp){
  resp.setEncoding('utf8');
  var arr = '';
  resp.on('data', function (chunk){
    arr += chunk;
  });
  resp.on('end', function (){
    var data = JSON.parse(arr);
    res.writeHead(200, {'Content-Type': 'application/json',});
    res.end(JSON.stringify(data));
  });
}).end(JSON.stringify(postData));

When I change the code to only accept data from the post body, IIS returns an HTTP 500 error. The new WEB API Service looks like the following.

namespace Approver.Controllers 
{
  public class UtilityController : ApiController 
 {
    public UserInfo AuthenticateUser(UserAuthentication userAuth) 
    {
      return UtilityBo.AuthenticateUser(userAuth); 
    } 
  } 
}

namespace Approver.Models 
{
  public class UserAuthentication 
  {
    [Required] 
    public string UserId { get; set; }

    [Required] 
    public string Password { get; set; } 
  } 
}

The new Node code just strips the query parameters from the URL.

After doing some tests, I realized the web api never inserted data into the model, so userAuth always had null values. However, I tried posting the data via Chrome's REST Console, and it worked, so the Node.js piece must contain an error. How do I fix this?

I think you are getting an issue in Model Binding from the Uri.

Try expliciting specifying the FromUri attribute.

namespace Approver.Controllers 
{
  public class UtilityController : ApiController 
 {
    public UserInfo AuthenticateUser([FromUri] UserAuthentication userAuth) 
    {
      return UtilityBo.AuthenticateUser(userAuth); 
    } 
  } 
}

If you want the parameters to be bound from both body and uri try using

namespace Approver.Controllers 
{
  public class UtilityController : ApiController 
 {
    public UserInfo AuthenticateUser([ModelBinder] UserAuthentication userAuth) 
    {
      return UtilityBo.AuthenticateUser(userAuth); 
    } 
  } 
}

This article gives a good insight into Model Binding in ASP.NET Web API