I'm porting a legacy .NET application onto .NET Core Web API.
The legacy application exposes an API that must me ported 1:1.
I've got the following request paths working perfectly fine:
GET https://localhost:5001/MySuperController/user@example.com
GET https://localhost:5001/MySuperController/?username=user@example.com
POST https://localhost:5001/MySuperController/?username=user@example.com
swagger: GET https://localhost:5001/doc
BUT I'm having problems routing the following two paths coming to the root URL:
GET https://localhost:5001/?username=user@example.com
POST https://localhost:5001/?username=user@example.com
This is my controller and swagger registration:
app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
if (EnvironmentConfiguration.EnvironmentType == SystemConstants.DevEnvironment)
{
app.UseSwagger(s =>
{
s.RouteTemplate = "doc/{{documentName}}/docs.json";
});
app.UseSwaggerUI(c =>
{
c.RoutePrefix = "doc";
c.SwaggerEndpoint($"../doc/v1/docs.json", "API reference");
});
}
And this is the controller simplified implementation:
[Route("[controller]")]
[ApiController]
public class MySuperController
{
// GET https://localhost:5001/MySuperController/user@example.com
[HttpGet("{emailaddress}")]
public IActionResult Get(...) {...}
// GET https://localhost:5001/MySuperController/?username=user@example.com
[HttpGet()]
public IActionResult Get(...) {...}
// POST https://localhost:5001/MySuperController/?username=user@example.com
[HttpPost()]
public async Task<IActionResult> Post(...) {...}
}
To support the following two queries, I've added the [Route("")]
prefix. But now I'm matching the https://localhost:5001/doc
into the first controller action, with {emailaddress}
being filled with "doc"
.
GET https://localhost:5001/?username=user@example.com
POST https://localhost:5001/?username=user@example.com
[Route("[controller]")]
[Route("")]
[ApiController]
public class MySuperController
{
// also matches https://localhost:5001/doc now :(
// GET https://localhost:5001/MySuperController/user@example.com
[HttpGet("{emailaddress}")]
public IActionResult Get(...) {...}
// GET https://localhost:5001/?username=user@example.com
// GET https://localhost:5001/MySuperController/?username=user@example.com
[HttpGet()]
public IActionResult Get(...) {...}
// POST https://localhost:5001/?username=user@example.com
// POST https://localhost:5001/MySuperController/?username=user@example.com
[HttpPost()]
public async Task<IActionResult> Post(...) {...}
}
What's the most idiomatic way to route these queries correctly with Web API? I would prefer not to split the controller into multiple controllers if at all possible.
Many thanks to Martin Costello's comment, I worked out the following:
[ApiController]
public class MySuperController
{
[HttpGet("[controller]/{emailaddress}")]
public IActionResult Get(...) {...}
[HttpGet("[controller]")]
[HttpGet("/")]
public IActionResult Get(...) {...}
[HttpPost("[controller]")]
[HttpPost("/")]
public async Task<IActionResult> Post(...) {...}
}
This way, the GET and POST to /
both get resolved with the correct action, while /doc
and any other endpoint are not intercepted by the first method, which stays under the controller.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.