Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Specify optional format extension with an empty route

My controller looks something like:

[FormatFilter]
[Route("api/foo")]
public class FooController : Controller
{
    [HttpPost("")]
    public IActionResult Foo()
    {
        ...
    }
}

I want to add an optional format extension as documented here. However, I want the route to end up like `/api/foo.json'. The following fails spectacularly, returning 404s for all variations.

[HttpPost(".{format?}"]

My next thought was doing something like:

[HttpPost("foo.{format?}")]

Effectively moving that portion of the controller-scoped route to the action. However, that then raises a 500, with the error:

Error: In the segment 'foo.{format?}', the optional parameter 'format' is preceded by an invalid segment 'foo.'. Only a period (.) can precede an optional parameter.

Apparently, the only thing that will work is something along the lines of:

[HttpPost("{id}.{format?}"]

In other words, it seems the optional format param must always follow another param in order to work, which seems like an absolutely bone-headed limitation to me. Am I missing something here? Any ideas of someway to make this work with static routes like this one?

like image 560
Chris Pratt Avatar asked Aug 23 '17 04:08

Chris Pratt


2 Answers

easy peasy *(after alot of trial & errors)

[FormatFilter]
[HttpPost("foo"), HttpPost("foo.{format}")]
public class FooController : Controller
{
    [HttpPost("")]
    public IActionResult Foo()
    {
        ...
    }
}

or

[FormatFilter]
    [HttpPost, Route("foo"), Route("foo.{format}")]
    public class FooController : Controller
    {
        [HttpPost("")]
        public IActionResult Foo()
        {
            ...
        }
    }

*tips:

  • the optional parameter 'format' is preceded by an invalid segment 'foo.'. Only a period (.) can precede an optional parameter
  • an action accept more than one route template
like image 108
McKabue Avatar answered Oct 19 '22 21:10

McKabue


I gave up too soon, apparently, though this has to be one of the most ridiculous solutions I've ever conceived.

[HttpPost("~/api/{foo=foo}.{format?}")]

Essentially, I'm just creating a dummy param my action doesn't actually take with a default value of the path piece I want there. That satisfies the requirement that the optional format param follow another param, while still letting me statically set my route.

The first portion (~/api/) is just a way of specifying the piece of the path without having to change my controller-scoped route. Any other actions still get prefixed with api/foo/, in other words.

Whatever works, I guess.

like image 26
Chris Pratt Avatar answered Oct 19 '22 21:10

Chris Pratt