Return to Article List

How Hard Can it be to Pass an Integer?

02/24/15

Sending a variable to a Web API turned out much trickier than expected. If the stars align, it can go direct via Request URI or POST body, but if you want a sure thing, gift wrap it in an object.

At the tail end of last week, I met two new technologies: ASP.NET Web API and AngularJS. This, of course, meant redoing the programming exercises that have previously been written in JavaScript, C# console and C# MVC versions yet another way - as a Web API service with an AngularJS front end. It sounds simple enough since these are very basic functions, but it wasn’t. In fact, that battle is the main reason this post is a bit behind schedule.

The tricky part was passing variables to the Web API side in a manner it would cheerfully accept. Most of the class struggled with this. How hard can it be to pass an array of integers from one program (i.e. AngularJS) to another (i.e. the Web API)? Or even a single integer for that matter? For us newbies, it turned out to be a real challenge.

For starters, apparently where Web API looks for parameters depends on what type the parameter is, not necessarily whether you sent it via GET or POST. According to the ASP.NET Web site, if the expected parameter is a primitive type (for example int, bool, double), Web API will look for it in the request URI; if the parameter is something more complex, like an object, Web API will seek it out in the message body. The programmer has the power to encourage it to work otherwise by placing [FromURI] or [FromBody] annotations next to the parameter name in the controller, something like this:

     public HttpResponseMessage MyMethod ([FromBody] int id)

This comes with gotchas, not the least of which is that you can only use [FromBody] on one parameter max per function. Throw into the mix the consideration that it’s generally encouraged to use the POST method if you’re sending variables to the server, which sends variables in the message body.

I went AROUND AND AROUND with this! After doing battle with various workarounds, most of us settled on some combination of the following two methods:

Method A: Use data annotations

Sender (AngularJS):

$http.post(apiPath, num)           // num is in integer              
    .then(function (response) { return response.data; });

Receiver (Web API):

public int MyMethod([FromBody] int num)
{
   etc.
}

Method B: Wrap primitive data types in object wrappers

Sender (AngularJS):

$http.post(apiPath, { nums: nums })   // object_field_name: the_array_of_integers.
    .then(function (response) { return response.data; });

Receiver (Web API):

// first create an object wrapper class for the incoming list of integers object

public class NumberList  //just a holder for a list of integers variable   
{
     public List<int> nums { get; set; }
}

// then the Web API controller method uses the NumberList class instead of int[] numList

public int MyMethod(NumberList numList)
{
     // do stuff with numList.nums
}

The ASP.Net website has a long, technical article explaining type converters, custom model binders, and value providers, but we did not get into a discussion of such things in class, and took our instructors’ word for it the wrapper method is the easiest way to achieve a fix. Once I have a better grip on Web API and AngularJS and a good chunk of time to spare, I’ll have to go back and give it a read.  Until then, I’ll become a professional wrapper.

Comments

On 02/24/15 David.Jolly said:
Interesting post. I never thought about the issue of handling the transmission of values between entities before. I guess this reflects my rather narrow view of the programming world. Even so, just from a practical perspective, it seems like the object wrapper method would be best. If I were coding, I'd want wrappers because: 1. It seems like it would be easier to debug and maintain. 2. I like the idea of all those nifty objects rattling, buzzing, and humming through netspace.. :)
On 03/20/15 Anne Martinez said:
p.s, To post a string without having to wrap it in an object, do this: In web API (receiver) public HttpResponseMessage MyMethod ([FromBody] string myString) In sender: $http.post('apiUrl', '"' + myStrl + '"') // note the literal quotes added to myStr

Add Comment

Return to Article List