Nickolodeon
Nickolodeon

Reputation: 2956

WebApi parameters

I am very new to WebApi and don't understand parameters mapping. I had a controller with HttpGet method with 2 parameters. In WebApiConfig mapping defined like

config.Routes.MapHttpRoute(
                name: "MyActionApi",
                routeTemplate: "api/{controller}/{action}/{p},{q}");

which seemed to work fine.

By analogy I've added another controller (DetailsController) that has 3 parameter HttpGet method.

I've added

config.Routes.MapHttpRoute(
                name: "MyActionApi2",
                routeTemplate: "api/{controller}/{action}/{p},{q},{r}");

But navigating to

http://mysite/api/Details/CrossReport/12,14,Peter

gives 404 error and says

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

But navigating like this

http://mysite/api/Details/FilterByDate/12,14?q=10

gives correct results.

Why is that? I'd like to have it comma separated as in the first case. And why it works in first case but not the second one?

Working controller's method:

public IEnumerable<Order> FilterByDate(DateTime dateStart, DateTime dateEnd).

Not working:

public IEnumerable<Detail> FilterByDate(DateTime dateStart, DateTime dateEnd, int maxCount)

Both have HttpGet attribute.

Upvotes: 0

Views: 1250

Answers (3)

acnagrellos
acnagrellos

Reputation: 51

There are two types of parameters in WebApi: parameters in routes and parameters in body/url.

Parameter in route

In this example the id param is in the route.

http://mysite/api/Details/CrossReport/{id}

The route params are separate by "/" and there are part of the route.

http://mysite/api/Details/CrossReport/{id}/{name}/{detailId}

In your web api controller you must be:

public IEnumerable<Order> FilterByDate(int id, string name, int detailId)

Parameter in body/url

The parameters in url are separate by & and all this params are after a ? in route. For example.

http://mysite/api/Details/CrossReport?id=3&name="john"&detailId=5

And in your web api controller is the same:

public IEnumerable<Order> FilterByDate(int id, string name, int detailId)

If the object is compound by others properties:

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

You can only have one in the body of the message and you have to send in the body on the message and your web api controller receipt them:

public IEnumerable<Order> FilterByDate(MyObject obj)

Upvotes: 0

Lenny
Lenny

Reputation: 195

One thought, have you made sure that MyActionApi2 ahead of MyActionApi in you routing config? If I am not mistaken, It looks for the first possible match... and so MyActionApi would match (even if there are 3 parameters)

Upvotes: 1

Youssef Moussaoui
Youssef Moussaoui

Reputation: 12395

You need to define a matching action. Try adding an action with the following signature on your DetailsController class:

[HttpGet]
public IEnumerable<Detail> CrossReport(string p, string q, string r)

As you see, the action name and parameter names must match what you have on your route.

Upvotes: 1

Related Questions