1

I'm currently having a problem with a Web Api I'm working on.

I have a controller with two Get methods. one which returns a list of objects. the other which returns a list of the same object, but filtered based on some parameters that are passed in. Like so:

public IList<MyObject> Get(int id)
{
  //Code here looks up data, for that Id
}

public IList<MyObject> Get(int id, string filterData1, string filterData2)
{
  //code here looks up the same data, but filters it based on 'filterData1' and 'filterData2'
}

I cannot make the routes work for this. Especially as the Api help page seems to display the same url multiple times.

my routes look like:

            config.Routes.MapHttpRoute(
            name: "FilterRoute",
            routeTemplate:  "api/Mycontroller/{Id}/{filterData1}/{filterData2}",
            defaults: new { controller = "Mycontroller" }
        );

        config.Routes.MapHttpRoute(
            name: "normalRoute",
            routeTemplate: "api/Mycontroller/{Id}",
            defaults: new { controller = "Mycontroller" }
        );

Anyone know?

Also, is it possible to change my filtered method to something like

public IList<MyObject> Get(int Id, FilterDataObject filterData)
{
   //code here
}

Or can you not pass complex objects on a Get?

3
  • what urls are you trying? Commented Oct 16, 2013 at 16:02
  • server/api/MyController/1/"someString"/"someOtherString" and server/api/Mycontroller/1 Commented Oct 16, 2013 at 16:03
  • The URLs you trying are wrong to the routes you are creating (look at my response). Commented Oct 16, 2013 at 16:10

2 Answers 2

1

Lets say you have the following route:

routes.MapHttpRoute(
    name: "Default", 
    routeTemplate: "api/{controller}/{id}/{p1}/{p2}",
    defaults: new { id = RouteParameter.Optional, p1 = RouteParameter.Optional, p2 = RouteParameter.Optional });

GET api/controller?p1=100 map to public HttpResponseMessage Get(int p1) {}

GET api/controller/1?p1=100 map to public HttpResponseMessage Get(int id, int p1) {}

GET api/controller/1 map to public HttpResponseMessage Get(int id) {}

and so on...

GET and complex model bind: by definition a complex model should be in the request body (verb independent) (a url contains a length limitation that can broke complex models). You can force the WebApi to look for the complex model in the URL by doing:

routes.MapHttpRoute(
    name: "Default", 
    routeTemplate: "api/{controller}/{customer}");

public class Customer
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public HttpResponseMessage Get([FromUri] Customer customer) {};

GET api/customers?id=1&name=Some+name

Just a note: GET with complex types, most of the time (like my example) makes no sense. Why should you get a customer by id and name? By definition a complex type expects a POST (CREATE) or a PUT (UPDATE).

To call with subfolders structure, try:

routes.MapHttpRoute(
    "MyRoute",
    "api/{controller}/{id}/{p1}/{p2}",
    new { id = UrlParameter.Optional, p1 = UrlParameter.Optional, p2 = UrlParameter.Optional, Action = "Get"});

GET /api/controller/2134324/123213/31232312

public HttpResponseMessage Get(int id, int p1, int p2) {};
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. I completely agree with the fact that this should be a Post. Infact it was a Post but the powers that be disagree, so here I am. As for the routing, I see what you're saying. the problem I am having, however is that I am using the nuGet package that adds documentation (a help page) to the Api. The routes it defines gives me the Url in the format you described, like 'api/controller/1?p1=p1' but i want to explicitly display them as parameters, so api/controller/1/parameter1
Thanks, the route with the optional parameters works. upvoted. I still believe this is the wrong way to tackle this and that posting an object of the filter data up is the better solution. But this will do for now!
1

Try looking at the attribute routing nuget package. This allows you to define custom urls to each method in your controller.

With regards to your second question you can't send complex objects over get requests as there's no request body to hold the values, you will need to use a POST method to do this.

Comments

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.