0

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

1 Answer 1

1

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)
{
    ...
}
Sign up to request clarification or add additional context in comments.

1 Comment

This works, thank you. I'm aware that passing such complex parameters should be avoided in case of GET functions but what if I don't have the choice ? Should I use POST ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.