ASP.NET Web API and Query Strings

The ASP.NET Web API is a framework to create a Web service.

WebApiWithQueryStringDemo

I think of a Web service as a black box that sits out on a network or the Internet, waiting for a request that looks like:

ht_p://someMachine:12345/api/(the request)

(I removed a ‘t’ from the URL so my lame blog software doesn’t go crazy). Then the service processes the request and sends a response result back, usually in the form of data which can then be used by the requestor (such as pasting the result into a Web page).

In the URL template above, “(the request)” can take two main forms, a RESTful format or a query string format. A query string format might look like:

ht_p://someMachine:12345/api/AlphaBeta?alpha=4&beta=5

And a RESTful format might look like:

ht_p://someMachine:12345/api/AlphaBeta/4/5

The RESTful format is the usual, default approach used by Web API. For either format, the Register method in file WebApiConfig.cs would look like:

public static class WebApiConfig
{
  public static void Register(HttpConfiguration config)
  {
    config.MapHttpAttributeRoutes();
    config.Routes.MapHttpRoute(
      name: "DefaultApi",
      routeTemplate: "api/{controller}/{alpha}/{beta}",
      defaults: new { alpha = RouteParameter.Optional,
        beta = RouteParameter.Optional }
    );
  }
}

For either a RESTful or query string format, a Controller that calculates 2 times alpha plus 3 times beta would look like:

public class AlphaBetaController : ApiController
{
  public int Get(string alpha, string beta)
  {
    int sum = 0;
    sum = 2 * int.Parse(alpha) +
          3 * int.Parse(beta);
    return sum;
  }
}

This Controller could be called by either

ht_p://someMachine/api/AlphaBeta/4/5

or

ht_p://someMachine/api/AlphaBet?alpha=4&beta=5

But a query string could also be processed like this:

public class AlphaBetaController : ApiController
{
  public int Get(string alpha, string beta)
  {
    var pairs = this.Request.GetQueryNameValuePairs();
    int sum = 0;
    foreach (KeyValuePair kvp in pairs)
    {
      if (kvp.Key == "alpha")
        sum += 2 * int.Parse(kvp.Value);
      else if (kvp.Key == "beta")
        sum += 3 * int.Parse(kvp.Value);
    }
    return sum;
  }
}

This Controller would process

ht_p://someMachine/api/AlphaBeta?alpha=4&beta=5

correctly but would not calculate

ht_p://someMachine/api/AlphaBeta/4/5

correctly. The minor problem with this Controller is that it doesn’t use its parameters, alpha and beta. So another approach that works only with the query string request format is to ditch the explicit parameters. The Controller would look like:

public int Get()
{
  var pairs = this.Request.GetQueryNameValuePairs();
  int sum = 0;
  foreach (KeyValuePair kvp in pairs)
. . .

where the configuration has only the {controller} component like:

config.Routes.MapHttpRoute(
  name: "DefaultApi",
  routeTemplate: "api/{controller}"

Another alternative, but one that I don’t recommend, is to craft your own custom query string along the lines of “alpha_4_beta_5” and have the Get() method accept it as one string, and then parse the custom format yourself like string[] tokens = cqString.Parse(‘_’).

The morals of the story are: 1.) unless you really need them, it’s generally somewhat better to avoid query strings with Web API, 2.) if you do use a query string, I recommend the empty-parameter Get() technique in most situations.

Advertisements
This entry was posted in Machine Learning. Bookmark the permalink.