Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing querystring parameters without using OData conventions?

Is there a way to pass querystring parameters to an ASP.NET MVC4 Web Api controller without using the OData conventions outlined here?

http://www.asp.net/web-api/overview/web-api-routing-and-actions/paging-and-querying

I have some repository methods built using Dapper that don't support IQueryable and want to be able to manually paginate them without using the OData conventions, but whenever I try doing it the traditional ASP.NET way I get "route not found" errors.

For instance, here's a route:

context.Routes.MapHttpRoute(
           name: "APIv1_api_pagination",
           routeTemplate: "api/v1/{controller}/{id}",
           defaults: new { area = AreaName, controller = "category", offset = 0, count = 100});

And here's the signature to match

public class CategoryController : ApiController
{
    // GET /api/<controller>
    public HttpResponseMessage Get(int id, int offset = 0, int count = 0)

And whenever I pass the following query:

http://localhost/api/v1/category/1?offset=10

I get the following error:

No action was found on the controller 'Category' that matches the request.

Any suggestions on how to work with querystrings sanely in ASP.NET MVC4 Web Api?

like image 710
Aaronontheweb Avatar asked Jun 05 '12 05:06

Aaronontheweb


2 Answers

When you start to use querystring you actually call exact method of controller with its parameters. What I prefer you to change your router like :

context.Routes.MapHttpRoute(
       name: "APIv1_api_pagination",
       routeTemplate: "api/v1/{controller}/{action}/{id}",
       defaults: new { area = AreaName, controller = "category", offset = 0, count = 100});

and then change your method into

public HttpResponseMessage Items(int id, int offset = 0, int count = 0);

From now on whenever you query like

http://localhost/api/v1/category/Items?id=1&offset=10&count=0

it will run.

Another method came to my mind while writing this. I don't know if it works but try to change your router like

context.Routes.MapHttpRoute(
       name: "APIv1_api_pagination",
       routeTemplate: "api/v1/{controller}/{id}/{offset}/{count}",
       defaults: new { area = AreaName, controller = "category", offset = RouteParameter.Optional, count = RouteParameter.Optional});
like image 102
kkocabiyik Avatar answered Oct 19 '22 12:10

kkocabiyik


In this instance, the issue I was running into was the fact that I had multiple overloads for GET on my WebApi controller instance. When I removed those (and condensed everything down to one Get method with more optional parameters and control-flow inside the method itself) everything worked as expected.

like image 39
Aaronontheweb Avatar answered Oct 19 '22 11:10

Aaronontheweb