0

Is there a way to automatically add a suffix on all endpoint routes e.g .json.

v1/users.json
v1/users/{id}.json

so what I have tried so far is I created a BaseController which look like this

[ApiController]
[Route("v1/[controller].json")]
public class BaseController : ControllerBase
{
}

but every time I use it to my controller it looks like this

v1/users.json
v1/users.json/{id}
5
  • 1
    parameters are passed to the controller actions. so {id}.json should be mapped to a controller action and not to the controller. Commented Mar 2, 2022 at 2:08
  • @Chetan so needed to add on each actions always? Is there a route config feature that could like add it as suffix always? Commented Mar 2, 2022 at 2:14
  • 1
    You could maybe use the rewrite middleware to accept .json on all endpoints but drop it during routing: learn.microsoft.com/en-us/aspnet/core/fundamentals/… Commented Mar 2, 2022 at 2:17
  • 1
    how about routes.MapRoute Commented Mar 2, 2022 at 2:21
  • Ill take a look first on what you guys suggested. thank you Commented Mar 2, 2022 at 2:27

2 Answers 2

2

You can add extra routing to the actual endpoints rather than the controllers

[ApiController]
[Route("v1/[controller]")]
public class BaseController : ControllerBase
{
    [HttpGet(".json")]
    public IActionResult Get()
    {
    
    }
    
    // Without Route Parameters
    [HttpGet("{id}.json")]
    public IActionResult Get([FromRoute] int id)
    {
          ...
    }

    // With Route and Query Parameters
    [HttpGet("{id}.json/friend")]
    public IActionResult Get([FromRoute]int id,[FromQuery] string friendName)
    {
          ...
    }

    // With Route and Query Parameters and Body
    [HttpPost("{id}.json/friends")]
    public IActionResult Get([FromRoute]int id,[FromQuery] string message, [FromBody]IFilter filter)
    {
          ...
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

I can say this is a way to do it. But what if you have query parameters on get endpoints?
@Carlo Then you could end up with something like /v1/base/123.json?abc=6
@CarloLuisito I've updated the answer and it shows how to do QueryParams, Route Params and Body Params all in one rquest.
Im thinking the problem too is .json still needs to be added on specific endpoints that belong only to a specific controller?
1

You could use the URL Rewriting Middleware to accept URLs with .json and then simply remove it. So something like:

/api/users/123/picture.json?query=123

would become:

/api/users/123/picture?query=123

You can do this by adding the following code to your Startup's Configure method:

var rewriteOptions = new RewriteOptions()
    .AddRewrite(@"^(.*?)(?:\.json)(\?.*)?$", "$1$2");
app.UseRewriter(rewriteOptions);

See the docs for more information.

Caveat: If you use Url.Action(...), etc. to generate a URL within code, then it won't include .json. The rewrite only affects incoming requests.

5 Comments

Is there way to force the endpoints to have .json and return not found if it doesnt?
@Carlo You could add a rewrite on ^(?!.*?\.json) (this should come above the .AddRewrite I added above) to redirect to a non-existent endpoint, or perhaps create a custom IRule implementation that returns a 404 result in that case.
I tried what you have above, but seems to be not working. localhost:5001/v1/users - working localhost:5001/v1/users.json - not working
@Carlo The order in which you apply middleware to the pipeline matters. If you put it below app.UseRouting();, for example, it won't work becauses routing has already occurred before it runs.
You'll also want it before app.UseStaticFiles(); so that the static file middleware doesn't try and serve the request.

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.