2014-05-20 16 views
5

sto leggendo su Attribute Routing in Web API 2 da hereRouting in ASP NET API Web - Per le diverse versioni di un API

L'articolo dice,

Here are some other patterns that attribute routing makes easy. 

API versioning 

In this example, “/api/v1/products” would be routed to a different controller than “/api/v2/products”. 

/api/v1/products 
/api/v2/products 

Come mai?

EDIT: Vorrei fare questo in Normale Routing:

public static class WebApiConfig 
{ 
    public static void Register(HttpConfiguration config) 
    { 
     config.Routes.MapHttpRoute(
      name: "DefaultApi", 
      routeTemplate: "api/v2/products", 
      defaults: new { controller = V2_Products } 
     ); 

     config.Routes.MapHttpRoute(
      name: "DefaultApi", 
      routeTemplate: "api/v1/products", 
      defaults: new { controller = V1_Products } 
     ); 
    } 
} 

Qualcuno mi potrebbe spiegare come fare questo in modo Attribute Routing? E come mai usare Attribute routing è più facile e conveniente per questo esempio (secondo l'articolo)?

+0

Questo non risponde direttamente alla domanda dell'OP, ma mi è piaciuto molto questo post sul blog perché approfondisce i vari approcci alla versione di un'API: https: // www. troyhunt.com/your-api-versioning-is-wrong-which-is/ – HeyZiko

risposta

6

Esistono molti modi per implementare il versionning con il routing degli attributi; Un modo davvero semplice è quello di utilizzare l'attributo RoutePrefix per ogni versione del vostro ApiController

[RoutePrefix("v1")] 
public class V1_ProductsController : ApiController 
{ 
    [Route("products")] 
    public IEnumerable<string> Get() 
    { 
     return new string[] { "v1-product1", "v1-product2" }; 
    } 
    //.... 
} 


[RoutePrefix("v2")] 
public class V2_ProductsController : ApiController 
{ 
    [Route("products")] 
    public IEnumerable<string> Get() 
    { 
     return new string[] { "v2-product1", "v2-product2" }; 
    } 
    //.... 
} 

/v1/products va alla prima versione di /v2/products va al secondo.

3

Un altro modo semplice è configurare il percorso come API/{cartella}/{controller}/{azione} dove nella cartella è possibile assegnare un nome come V1 o V2.

Un buon modo può essere implementando il proprio selettore Controller. È possibile utilizzare this link per ulteriori informazioni.

L'interfaccia utilizzata da Web API per selezionare un controller è IHttpControllerSelector. Il metodo più importante su questa interfaccia è SelectController, che seleziona un controller per un determinato HttpRequestMessage.

8

Si può fare l'override DefaultHttpControllerSelector

ci si sostituisce il metodo di selectcontroller

public override HttpControllerDescriptor SelectController(HttpRequestMessage request) 
      { 
       HttpControllerDescriptor controllerDescriptor = null; 
       IDictionary<string, HttpControllerDescriptor> controllers = GetControllerMapping(); 

       IHttpRouteData routeData = request.GetRouteData(); 

       if (routeData == null) 
       { 
        throw new HttpResponseException(HttpStatusCode.NotFound); 
       } 

       object apiVersion; 
       if (!routeData.Values.TryGetValue("Version", out apiVersion)) 
       { 
        apiVersion = "1"; 
       } 


       object controllerName; 
       if (!routeData.Values.TryGetValue("controller", out controllerName)) 
       { 
        controllerName = string.Empty; 
       } 
       if (controllerName == null) 
       { 
        throw new HttpResponseException(HttpStatusCode.NotFound); 
       } 

       string newControllerName = String.Concat(controllerName.ToString(), "V", apiVersion); 

       if (controllers.TryGetValue(newControllerName, out controllerDescriptor)) 
       { 
        return controllerDescriptor; 
       } 
       if (controllers.TryGetValue(controllerName.ToString(), out controllerDescriptor)) 
       { 
        return controllerDescriptor; 
       } 
       throw new HttpResponseException(HttpStatusCode.NotFound); 

      } 

percorsi Poi si sta aggiungendo webapiconfig

config.Routes.MapHttpRoute(
       name: "DefaultApi", 
       routeTemplate: "api/{version}/{controller}/{id}", 
       defaults: new { id = RouteParameter.Optional } 
      ); 

e registrare il selettore di controllo in webapiconfig

config.Services.Replace(typeof(IHttpControllerSelector), new ApiVersioningSelector(config)); 

Quindi da ora, se si assegna il nome controller ProductsV1Controller, verrà reffer/api/v1/products. Inoltre, tieni presente che il mio esempio supporta anche percorsi senza versione, quindi se v1 non viene trovato cercherà di verificare se ProductsController esiste

PS. Il codice è aggiornato un bug era lì :(

+0

Ho un problema con questo metodo quando definisco il percorso personalizzato per ciascun metho API, cioè vorrei definire Route per il mio metodo [Route (" Prodotto ")]. Qualche idea su come possiamo definire il percorso personalizzato insieme a questo override? – DSA

+0

Quindi cosa vuoi fare se il percorso è lì? –

+0

Diciamo che ho due metodi di pubblicazione differ con lo stesso parametro, devo definire un percorso personalizzato per ciascuno. Ma se si definisce il percorso, questa sovrascrittura smette di funzionare. Dice, il metodo non è permesso. – DSA

Problemi correlati