2

Angular Code:

 getAuthorizationStatus: function () {
                    var deferred = $q.defer();
                     $http({
                        method: "POST",
                        url: url,
                        data: {
                            username: $scope.username,
                            password: $scope.password
                        },
                        contentType: 'application/json',
                        headers: {
                        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
                    }
                    }).success(deferred.resolve)
                      .error(deferred.reject);
                    return deferred.promise;
                },

My Server side code:

  [HttpPost]
        public int ValidateUser([FromBody]Credentials credentials)
        {
            try
            {
                string username = credentials.username;
                string password = credentials.password;
          //Do stuff
        }
        catch (Exception ex)
        {
            throw ex;
            return -1;
        }

        return -1; // not valid user
    }

The problem I am having is I am able to hit the Api Method but the data inside is always null. I have tried several combinations like this:

  data:  JSON.stringify({
                            "username" : "username",
                            "password":"mypassword"
                        }),

No dice.

What am I doing in wrong ?

w2olves
  • 2,229
  • 10
  • 33
  • 60

3 Answers3

1

Enclose your data in $.param()

Example :

data: $.param({ username: $scope.username,password: $scope.password })

amanpurohit
  • 1,246
  • 11
  • 19
  • 3
    Not everyone has access to or wants jQuery in their project. You could also use a request transformer I believe. http://stackoverflow.com/a/1714899/1784301 – Sean Larkin Nov 13 '15 at 17:29
  • Yes, my solution is perfect if you are using jQuery and it makes it really simple to implement. Or if you don't want to use jquery you can refer Sean Larkin's link. – amanpurohit Nov 13 '15 at 17:33
  • 1
    @amanpurohit, your approach will solve the problem but add an additional dependency. But your answer will help a lot of people I am sure. – w2olves Nov 13 '15 at 17:36
  • @w2olves, I mentioned it that my solution is apt if the project is jquery dependent.! – amanpurohit Nov 13 '15 at 17:38
1

I would instead trying to change the default and appropriate behavior of $http's POST, instead let the server read the data from the right place. Taken from MVC controller : get JSON object from HTTP body?:

[HttpPost]
public ActionResult Index(int? id)
{
    Stream req = Request.InputStream;
    req.Seek(0, System.IO.SeekOrigin.Begin);
    string json = new StreamReader(req).ReadToEnd();

    InputClass input = null;
    try
    {
        // assuming JSON.net/Newtonsoft library from http://json.codeplex.com/
        input = JsonConvert.DeserializeObject<InputClass>(json)
    }

    catch (Exception ex)
    {
        // Try and handle malformed POST body
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }

    //do stuff

}

It turns out that MVC doesn't really bind the POST body to any particular class. Nor can you just fetch the POST body as a param of the ActionResult (suggested in another answer). Fair enough. You need to fetch it from the request stream yourself and process it.

Community
  • 1
  • 1
Sean Larkin
  • 6,290
  • 1
  • 28
  • 43
0

Using [FromBody] beside the action input param is enough to get the data from request. Your problem is that you override the content-type in your Angular code through headers:

contentType: 'application/json',
headers: {
   'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' //*** Remove this!
}

It must be 'application/json' in order to send json data. Just remove that headers and it should work normally.

S.Serpooshan
  • 7,608
  • 4
  • 33
  • 61