简体   繁体   中英

.net web API: How to retrieve routes/route templates from controller class method which represents an API operation?

I need to build an call back URL (kindof web hook) and therefore I'm required to get the route path of a given class method which represents an API operation.

Let's say, my controller looks like this:

[Route("api/[controller]")]
public class MyController : ControllerBase
{
    public MyController(ILogger<ServicesController> logger)
    {
    }

    [HttpPost("operationVerb1/{what}")]
    public string DoSomething(string what)
    {
        IEnumerable<RouteEntryTypeOrSo> operationRoutes;
        
        if (what == "looks like for verb2 ...")
        {
            operationRoutes = ?? // get routes for MyController.DoSomething2
        }
        else if (what == "looks like something else ...")
        {
            operationRoutes = ?? // get routes for MyController.DoSomething3
        }

        // pick an adequate route of the list
        var callbackRoute = operationRoutes.FirstOrDefault(x => whatevercondition);

        // create a URL
        var callbackUrl = new Uri("https://" + Request.Host.ToUriComponent() + callbackRoute.EndpointOrWhateverProp);

        // call back URL whould then look like "https://blablabla.com/api/operationVerb2"

        return $"Ok, we're doing something, but in half an hour you must call ...{callbackUrl}";
    }

    [HttpGet("operationVerb2")]
    public string DoSomething2()
    {
        // do whatever
    }

    [HttpGet("operationVerb3")]
    public string DoSomething3()
    {
        // do whatever
    }
}

How to achieve?

[Edit]: The target operation is not neccessarily on the same controller which should generate the URL. The example above is just a very simple example.

I'm using .net 6.0.

I tried to achieve something similar using IApiDescriptionGroupCollectionProvider

see if this fits your need.

[Route("api/[controller]")]
public class MyController : ControllerBase
{
    private readonly IApiDescriptionGroupCollectionProvider _apiDescriptionsProvider;
    public MyController(ILogger<ServicesController> logger,
           IApiDescriptionGroupCollectionProvider apiDescriptionsProvider)
    {
       apiDescriptionsProvider = apiDescriptionsProvider;
    }

    [HttpPost("operationVerb1/{what}")]
    public string DoSomething(string what)
    {
       var applicableApiDescriptions = 
    _apiDescriptionsProvider.ApiDescriptionGroups.Items
           .SelectMany(group => group.Items);

        IEnumerable<ApiDescription> operationRoutes;   
    
        if (what == "looks like for verb2 ...")
        {
           operationRoutes = applicableApiDescriptions.Where(a => a.GroupName == "operationVerb2"); // get routes for MyController.DoSomething2
        }
        else if (what == "looks like something else ...")
        {
          operationRoutes = applicableApiDescriptions.Where(a => a.GroupName == "operationVerb3"); // get routes for MyController.DoSomething3
        }

    // pick an adequate route of the list
    var callbackRoute = operationRoutes.FirstOrDefault(x => whatevercondition);

    // create a URL
    var callbackUrl = new Uri("https://" + Request.Host.ToUriComponent() + "/"+ callbackRoute.RelativePath);

    // call back URL whould then look like "https://blablabla.com/api/operationVerb2"

    return $"Ok, we're doing something, but in half an hour you must call ...{callbackUrl}";
   }

   [HttpGet("operationVerb2")]
   [ApiExplorerSettings(GroupName = "operationVerb2")]
   public string DoSomething2()
   {
    // do whatever
   }

  [HttpGet("operationVerb3")]
  [ApiExplorerSettings(GroupName = "operationVerb3")]
  public string DoSomething3()
  {
    // do whatever
  }
}

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM