Thomas Perez
Thomas Perez

Reputation: 171

Passing complex JS objects from angular to c# WebApi with GET

I'm trying to pass complex objects from angular to a C# WebApi Controller. I have wrote this pointless code in order to learn.

JS code:

angular.module('app').controller('ExampleController', function($scope, $http) {
  var self = this;

  var obj = {
    val1: {
      val2: {
        val3: true
      }
    }
  };

  self.exampleGet = function() {
    $http.get('rest/myconso/exampleget', {
      params: {
        query: obj
      }
    }).then(function success(response) {
      console.log('success');
    }, function error(response) {
      console.log('error');
    });
  };

  self.examplePost = function() {
    $http.post('rest/myconso/examplepost', obj).then(function success(response) {
        console.log('success');
    }, function error(response) {
        console.log('error');
    });
  };
});

C# code:

public class ExampleController : ApiController
    {
        [Route("rest/myconso/examplepost")]
        [HttpPost]
        public IHttpActionResult ExamplePost(IDictionary<string, IDictionary<string, IDictionary<string, bool>>> query)
        {
            return Ok();
        }

        [Route("rest/myconso/exampleget")]
        [HttpGet]
        public IHttpActionResult ExampleGet([FromUri]IDictionary<string, IDictionary<string, IDictionary<string, bool>>> query)
        {
            return Ok();
        }
    }

The POST methods works perfectly as expected but not the GET method. The query parameter is always empty.

What is wrong with my code ?

Thanks

Upvotes: 0

Views: 1187

Answers (1)

Darin Dimitrov
Darin Dimitrov

Reputation: 1039468

The GET request that Angular makes is this:

/rest/myconso/exampleget?query=%7B%22val1%22:%7B%22val2%22:%7B%22val3%22:true%7D%7D%7D

which basically sends the query string parameter the value of {"val1":{"val2":{"val3":true}}}

There's no built-in mechanism in Web API that will bind this query string parameter to the dictionary object you expect. You will have to handle it manually:

public IHttpActionResult ExampleGet(string query)
{
    var result = JsonConvert.DeserializeObject<IDictionary<string, IDictionary<string, IDictionary<string, bool>>>>(query);
    ...
}

This being said, passing such complex and nested structures as GET parameters should in general be avoided. You'd better pass simple parameters:

$http.get('rest/myconso/exampleget?foo=bar&baz=bazinga')
    .then(function success(response) {
      console.log('success');
    }, function error(response) {
      console.log('error');
    });

which can be mapped to the following:

public IHttpActionResult ExampleGet(string foo, string baz)
{
    ...
}

Upvotes: 1

Related Questions