URL for Web API Management

I have a problem with the version of my web API:

[ApiVersion("1.0")]
[ApiVersion("2.0")]
[System.Web.Http.Route("api/v{version:apiVersion}/monitors")]
[ControllerName("Monitors")]
public sealed class MonitorsController : ApiController
{
   /* 
     /monitors/get?heartbeat=foo
   */
   [System.Web.Http.Route("api/v{version:apiVersion}/monitors/get")]
   [MapToApiVersion("1.0")]
   public JsonResult GetHeartbeatStatusV1(string heartbeat)
   {
      var x = new JsonResult {Data = "heartbeat v1"};
      return x;
   }
   [System.Web.Http.Route("api/v{version:apiVersion}/monitors/get")]
   [MapToApiVersion("2.0")]
   public JsonResult GetHeartbeatStatusV2(string heartbeat)
   {
      var x = new JsonResult { Data = "heartbeat v1" };
      return x;
   }
   /* 
      /monitors/get?alert=foo 
   */
   [System.Web.Http.Route("api/v{version:apiVersion}/monitors/get")]
   [MapToApiVersion("2.0")]
   public JsonResult GetAlertStatus(string alert)
   {
      var x = new JsonResult {Data = "alerts"};
      return x;
   }
   /* 
      /monitors/get?oDataQuery=foo 
   */
   [System.Web.Http.Route("monitors/get")]
   public JsonResult GetODataQuery(string oDataQuery)
   {
      var x = new JsonResult {Data = "oDataQuery"};
      return x;
   }
}

      

Above is my controller. I have a bunch of actions that I want to be able to call based on the version.

The problem is I also need all of them in order to be / get and then decide which method to call based on the parameter name, which is why I have:

[System.Web.Http.Route("api/v{version:apiVersion}/monitors/get")]

      

I thought I could decorate the method [MapToApiVersion("1.0")]

and [MapToApiVersion("2.0")]

to recognize which method is being called. However, in the exmaple posted, if I call api/v1.0/monitors/get?heartbeat=foo

, I get multiple actions error. If I call v2.0 it says it cannot find any method at all.

?

I would like to be able to do

http://foo:blah/api/v1.0/monitors/get?heartbeat=foo

http://foo:blah/api/v2.0/monitors/get?heartbeat=foo

http://foo:blah/api/v2.0/monitors/get?alert=foo

Is it possible?

EDIT


One thing I tried was splitting them into 2 different controllers in different namespaces.

[ApiVersion("2.0")]
[System.Web.Http.Route("api/v{version:apiVersion}/monitors")]
[ControllerName("Monitors")]
public sealed class MonitorsController : ApiController
{
    /* 
        /monitors/get?heartbeat=foo
    */
    [System.Web.Http.Route("api/v{version:apiVersion}/monitors/get")]
    [MapToApiVersion("2.0")]
    public JsonResult GetHeartbeatStatusV2(string heartbeat)
    {
        var x = new JsonResult {Data = "heartbeat v2"};
        return x;
    }
    /* 
        /monitors/get?alert=foo 
    */
    [System.Web.Http.Route("api/v{version:apiVersion}/monitors/get")]
    public JsonResult GetAlertStatus(string alert)
    {
        var x = new JsonResult {Data = "alerts"};
        return x;
    }

}

      

This error gets an error when searching multiple actions.

My WebApiConfig.cs looks like this:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        // Configure Web API to use only bearer token authentication.
        config.SuppressDefaultHostAuthentication();
        config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
        var constraintResolver = new DefaultInlineConstraintResolver
                                 {
                                     ConstraintMap =
                                     {
                                         ["apiVersion"] = typeof(ApiVersionRouteConstraint)
                                     }
                                 };
        config.MapHttpAttributeRoutes(constraintResolver);
        config.AddApiVersioning();
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/v{version:apiVersion}/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

      

+3


source to share


1 answer


How are you doing it right, but instead of using the attribute, ApiVersion

you can make it simpler and more straightforward Just give MapHttpRoute the default and you can let your controller in the same namespace and just change the nameMonitorsControllerV2



[RoutePrefix("api/V2.0/monitors")] 
public sealed class MonitorsControllerV2 : ApiController
{
    /* 
        /monitors/get?heartbeat=foo
    */

     [Route("GetHeartbeat")]
    public JsonResult GetHeartbeatStatusV2(string heartbeat)
    {
        var x = new JsonResult {Data = "heartbeat v2"};
        return x;
    }
    /* 
        /monitors/get?alert=foo 
    */
      [Route(" GetAlertStatus")]
    public JsonResult GetAlertStatus(string alert)
    {
        var x = new JsonResult {Data = "alerts"};
        return x;
    }

}

      

+2


source







All Articles