Come eseguire il controllo delle versioni in ASP.NET Core Web Api

In asp.net web api precedente, implemento DefaultHttpControllerSelector per specificare come desidero che la richiesta localizzi il mio controller. Ho spesso controller diversi con nomi diversi ma destinati agli stessi processi. L’unica differenza è che uno è di versione superiore rispetto all’altro.

Ad esempio, potrei avere un controller chiamato BookingV1Controller , che avrebbe dovuto gestire la versione uno del servizio. Avrei anche BookingV2Controller , che è stato progettato per gestire la versione due del servizio. Un’applicazione client farebbe quindi una richiesta al servizio con questo URL http://myservice.com/api/v2/booking/someaction?id=12 . Per gestire la richiesta, fornirei una implementazione personalizzata di DefaultHttpControllerSelector per selezionare la versione appropriata del controller richiesta in base alla versione richiesta.

Tuttavia, sembra che non ci sia un modo per farlo in ASP.NET Core . Ho cercato ovunque inutilmente. Nessuna documentazione che potrebbe aiutare entrambi.

Apprezzerei se qualcuno potesse essermi d’aiuto qui. Grazie.

AGGIORNAMENTO Vorrei anche sapere cosa fare se la versione è specificata in un’intestazione personalizzata. Es. X-Version:v1

AGGIORNAMENTO 2

Il requisito era che la versione del servizio non venisse esposta nell’URL. Se non è presente alcuna versione, il servizio ritorna con le istruzioni su come aggiungere la versione. Se un controller richiesto non è presente nella versione richiesta, il sistema cerca nelle versioni inferiori. Se lo trova in qualsiasi versione inferiore, lo usa. La ragione di ciò è impedire la ripetizione dei controller su tutte le versioni. Ma con ASP.NET Core, questo potrebbe non essere ansible.

Ho creato un pacchetto per questo scopo esattamente dopo aver sbattuto la testa su questo problema per alcuni giorni. Non richiede attributi.

https://github.com/GoAheadTours/NamespaceVersioning

In sintesi, è ansible registrare un IApplicationModelConvention nel file di avvio in grado di scorrere i controller e registrare i percorsi in base agli spazi dei nomi. Ho creato una cartella v1 e ho inserito il mio controller

La class che implementa IApplicationModelConvention implementa un metodo Apply con un parametro ApplicationModel che avrà accesso ai Controller nella tua app e ai percorsi esistenti. Se vedo che un controller non ha una route impostata nella mia class, ottengo la versione dallo spazio dei nomi e uso un prefisso URL predefinito per generare una route per quella versione.

 public void Apply(ApplicationModel application) { foreach (var controller in application.Controllers) { var hasRouteAttribute = controller.Selectors.Any(x => x.AttributeRouteModel != null); if (hasRouteAttribute) { continue; } var nameSpace = controller.ControllerType.Namespace.Split('.'); var version = nameSpace.FirstOrDefault(x => Regex.IsMatch(x, @"[v][\d*]")); if (string.IsNullOrEmpty(version)) { continue; } controller.Selectors[0].AttributeRouteModel = new AttributeRouteModel() { Template = string.Format(urlTemplate, apiPrefix, version, controller.ControllerName) }; } } 

Ho già tutto il codice su github e un collegamento al pacchetto su nuget

Questa è una domanda molto vecchia in cui mi sono imbattuto, ma ora ci sono soluzioni migliori. C’è questo pacchetto

Microsoft.AspNetCore.Mvc.Versioning

Quale ha un modo molto più ricco di implementare i controlli di controllo delle versioni. Questi includono la possibilità di utilizzare stringhe di query URL, percorsi URL, intestazioni o lettori di versioni personalizzate. Essere in grado di leggere la versione da HTTPContext ecc.

In breve, aggiungi il seguente nel tuo metodo ConfigureServices in startup.cs

 services.AddApiVersioning(o => { o.ReportApiVersions = true; o.AssumeDefaultVersionWhenUnspecified = true; o.DefaultApiVersion = new ApiVersion(1, 0); }); 

Quindi devi decorare i tuoi controller con ApiVersion.

 [ApiVersion("1.0")] [Route("api/home")] public class HomeV1Controller : Controller { [HttpGet] public string Get() => "Version 1"; } [ApiVersion("2.0")] [Route("api/home")] public class HomeV2Controller : Controller { [HttpGet] public string Get() => "Version 2"; } 

Puoi anche implementarlo nel percorso inserendolo nel percorso.

 [ApiVersion("1.0")] [Route("api/{version:apiVersion}/home")] public class HomeV1Controller : Controller { [HttpGet] public string Get() => "Version 1"; } [ApiVersion("2.0")] [Route("api/{version:apiVersion}/home")] public class HomeV2Controller : Controller { [HttpGet] public string Get() => "Version 2"; } 

Quando si scende a questo metodo di averlo effettivamente implementato tramite il pacchetto Microsoft, significa anche che si è in grado di deprecare le versioni, avere la versione discovery, accedere facilmente al numero di versione da HttpContext ecc. Nessuno dei quali si potrebbe davvero fare se è solo hardcoded nel tuo percorso.

Per maggiori informazioni (incluso l’utilizzo in un’intestazione):

Utilizzare gli attributi di instradamento per controllare le versioni.

vale a dire

 [Route("api/v1/[controller]")] public class BookingV1Controller : Controller { .... } [Route("api/v2/[controller]")] public class BookingV2Controller : Controller { .... } 

Per ulteriori informazioni relative alla migrazione da standard Web Api e .NET Core ASP.NET dare un’occhiata a: MSDN: migrazione da ASP.NET Web Api

Per questo aggiungi il versioning dell’API del servizio alle tue applicazioni ASP.NET Core

  public void ConfigureServices( IServiceCollection services ) { services.AddMvc(); services.AddApiVersioning(); // remaining other stuff omitted for brevity } 

VERSIONE DEL PARAMETRO DI QUERISTICA

 [ApiVersion( "2.0" )] [Route( "api/helloworld" )] public class HelloWorld2Controller : Controller { [HttpGet] public string Get() => "Hello world!"; } 

Quindi questo significa che per ottenere 2.0 su 1.0 in un altro Controller con lo stesso percorso, andresti qui:

/api/helloworld?api-version=2.0

possiamo avere lo stesso nome del controller con diversi spazi dei nomi

URL SEGMENTO DI SEGMENTO

  [ApiVersion( "1.0" )] [Route( "api/v{version:apiVersion}/[controller]" )] public class HelloWorldController : Controller { public string Get() => "Hello world!"; } [ApiVersion( "2.0" )] [ApiVersion( "3.0" )] [Route( "api/v{version:apiVersion}/helloworld" )] public class HelloWorld2Controller : Controller { [HttpGet] public string Get() => "Hello world v2!"; [HttpGet, MapToApiVersion( "3.0" )] public string GetV3() => "Hello world v3!"; } 

Controllo delle intestazioni

  public void ConfigureServices( IServiceCollection services ) { services.AddMvc(); services.AddApiVersioning(o => o.ApiVersionReader = new HeaderApiVersionReader("api-version")); } 

Quando esegui HeaderApiVersioning non sarai in grado di eseguire semplicemente un GET nel tuo browser, quindi userò Postman per aggiungere l’intestazione (o potrei usare Curl, o WGet, o PowerShell, o un Test unitario):

Immagine

si prega di fare riferimento https://www.hanselman.com/blog/ASPNETCoreRESTfulWebAPIVersioningMadeEasy.aspx