6

I am new to attribute routing, and I am not sure if this is even possible.

I have an attribute route, which works fine like this:

[HttpGet]
[Route("GetIssuesByFlag/{flag:int=3}")]
public IEnumerable<IssueDto> GetIssuesByFlag(int flag)

Now I want to add some extra optional parameters to narrow down my search, so I want to add 2 extra optional parameters.

What I have tried:

[HttpGet]
[Route("GetIssuesByFlag/{flag:int=3?}/{categoryId:int?}/{tagIds?}")]
public IEnumerable<IssueDto> GetIssuesByFlag(int flag , int? categoryId = null, int?[] tagIds = null)

This works fine if my call is /api/controller/1/2, but fails with 404 when it comes to /api/controller/1.

How can I achieve this?

Edit 1: Nkosi's answer below worked, however an extra modification was needed.

[HttpGet]
[Route("GetIssuesByFlag/{flag:int=3}/{tagIds?}/{categoryId:int?}")]
public IEnumerable<IssueDto> GetIssuesByFlag(int flag , List<int> tagIds, int? categoryId = null )

The list or array must be second as it is automatically null if no value is provided and cant be marked as optional with = null.

peterh
  • 11,875
  • 18
  • 85
  • 108
Harry
  • 3,333
  • 3
  • 18
  • 28
  • 1
    `{flag:int=3?}` is the problem. it is either optional `{flag:int?}` with the default value in the action or `{flag:int=3}`. You currently have 3 optional parameters. when you have just the 1 value routing table wont know which optional parameter you are referring to, hence the 404 – Nkosi Feb 08 '17 at 14:09
  • Nikosi's answer worked for me! Well the first one not the splitting one, having removed that everything works fine now – Harry Feb 08 '17 at 14:14
  • first one(the remove optional from flag) can you update it on answers so i can mark as correct? – Harry Feb 08 '17 at 14:15

2 Answers2

4

{flag:int=3?} is the problem. it is either optional {flag:int?} with the default value in the action or {flag:int=3}.

[HttpGet]
Route("GetIssuesByFlag/{flag:int=3}/{categoryId:int?}/{tagIds?}")]
public IEnumerable<IssueDto> GetIssuesByFlag(int flag , int? categoryId = null, int?[] tagIds = null)

You currently have 3 optional parameters. when you have just the 1 value routing table wont know which optional parameter you are referring to, hence the 404

Nkosi
  • 235,767
  • 35
  • 427
  • 472
1

Use a query string.

[HttpGet]
    [Route("GetIssuesByFlag/{flag:int=3?}")]
    public IEnumerable<IssueDto> GetIssuesByFlag(int flag, List<int> tagIds, int? categoryId = null)

Url: /getissuesbyflag/1?tagIds=2,5,6&categoryId=56

You really should use query strings for optional parameters and path parameters if they are required.

mambrow
  • 442
  • 5
  • 14
  • It works again if i provide all variables but if i provide just the flag it fails with "message": "No HTTP resource was found that matches the request URI 'https://localhost:44363/api/Issues/GetIssuesByFlag/1'.", "messageDetail": "No action was found on the controller 'Issues' that matches the request." – Harry Feb 08 '17 at 14:07