I have a client that will need to hit the same base endpoint url for multiple requests using rest HttpGet calls, each with unique query parameters and values. The function I need to map for each request will be determined by the value provided by the "request" query parameter. Is this possible to do inside of the app.UseEndpoints(), attributes on the endpoint functions, or a similar simple solution?
I'm a bit new to this part, and the docs don't have an example for this. What I have so far (doesn't work):
Startup.cs
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "test1",
pattern: "serviceapi",
constraints: new { request = "test1" }, //map action if param "request" value is "test1"?
defaults: new { controller = "ServiceApi", action = "TestRequest1" }
);
endpoints.MapControllerRoute(
name: "test2",
pattern: "serviceapi",
constraints: new { request = "test2" }, //map action if param "request" value is "test2"?
defaults: new { controller = "ServiceApi", action = "TestRequest2" }
);
});
what I want is when I use postman to send a get request to "{{url}}/api/serviceapi/?request=test1&uniqueparam1=foo", it runs the code in my ServiceApi.TestRequest1()
[Route("api/[controller]")]
ServiceApiController.cs
[HttpGet]
public async Task<IActionResult> TestRequest1([FromQuery]string request, [FromQuery]string uniqueparam1)
{
return Ok($"TestRequest1: {request} - {uniqueparam1}");
}
[HttpGet]
public async Task<IActionResult> TestRequest2([FromQuery]string request, [FromQuery]string uniqueparam2, [FromQuery]string uniqueparam3)
{
return Ok($"TestRequest2: {request} - {uniqueparam2}, {uniqueparam3}");
}
The error that I get currently with this code is that both functions were candidates: "Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException: The request matched multiple endpoints."
Thanks!
------ UPDATE ------
Thanks to Rena's answer, I was able to get this working:
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class RequestValueConstraintAttribute : ActionMethodSelectorAttribute
{
public string RequestValue { get; private set; }
private readonly string _requestParam = "request";
public RequestValueConstraintAttribute(string requestValue)
{
RequestValue = requestValue;
}
public override bool IsValidForRequest(RouteContext routeContext, ActionDescriptor action)
{
return (string)routeContext.HttpContext.Request.Query[_requestParam] == RequestValue;
}
}
ServiceApiController.cs
[Route("api/[controller]")]
[ApiController]
public class ServiceApiController : ControllerBase
{
[RequestValueConstraint("test1")] //uses this endpoint function if param "request" value is "test1"
[HttpGet]
public async Task<IActionResult> TestRequest1([FromQuery]string request, [FromQuery]string uniqueparam1)
{
return Ok($"TestRequest1: {request} - {uniqueparam1}");
}
[RequestValueConstraint("test2")] //uses this endpoint function if param "request" value is "test2"
[HttpGet]
public async Task<IActionResult> TestRequest2([FromQuery]string request, [FromQuery]string uniqueparam2, [FromQuery]string uniqueparam3)
{
return Ok($"TestRequest2: {request} - {uniqueparam2}, {uniqueparam3}");
}
}