2012-12-21 22 views
9

Ho un'app ASP.NET MVC 4. Voglio utilizzare la nuova funzionalità API Web per scopi di apprendimento. Voglio imparare come esporre lo stesso endpoint, ma fornirne diverse versioni. In altre parole, voglio esporre endpoint come la seguente:Esecuzione di azioni API Web in ASP.NET MVC 4

http://mysite/1.0/Products/1 
http://mysite/2.0/Products/1 

Nel tentativo di fare questo, ho aggiunto una directory "Api" all'interno della directory di default "controllori". All'interno della directory "Api", ho altre due directory: "Versione1-0" e "Versione2-0". Ciascuna di queste directory ha un ApiController denominato "ProductsController".

ho cercato di esporre gli endpoint aggiungendo la seguente definizione della rotta nel mio file WebApiConfig.cs:

config.Routes.MapHttpRoute(
    name: "1-0Api", 
    routeTemplate: "api/1.0/{controller}/{id}", 
    defaults: new { id = RouteParameter.Optional } 
); 

Purtroppo, non riesco a capire come esporre le azioni tramite gli URL che ho elencato sopra. Che cosa sto facendo di sbagliato? Grazie!

risposta

7

Probabilmente stai incontrando problemi perché i controller hanno lo stesso nome. Lo spazio dei nomi del controller o la cartella in cui si trova non ha alcuna importanza per WebAPI, solo il nome lo fa. La cosa più semplice che posso pensare è quello di rinominare il controller ProductsV1Controller e ProductsV2Controller e impostare due percorsi per puntare al controller:

config.Routes.MapHttpRoute(
    name: "1-0Api", 
    routeTemplate: "api/1.0/Products/{id}", 
    defaults: new { controller = "ProductsV1", id = RouteParameter.Optional } 
); 
config.Routes.MapHttpRoute(
    name: "2-0Api", 
    routeTemplate: "api/2.0/Products/{id}", 
    defaults: new { controller = "ProductsV2", id = RouteParameter.Optional } 
); 

Naturalmente, questo diventa disordinato se si dispone di più controller si desidera esporre in questa modo. Fammi vedere se non riesco a pensare a qualcosa di meglio per te.

+0

Attualmente, ho solo 1 controller (ProductsV1Controller) e non riesco ad accedere a quell'endpoint. Che cosa sto facendo di sbagliato? Non ci sono stati altri cambiamenti nel progetto. Ho avviato letteralmente un nuovo progetto ASP.NET MVC 4 e volevo aggiungere un controller con versione. –

+0

Diverse cose potrebbero essere sbagliate. Il controller potrebbe non essere una classe pubblica, il controller potrebbe non derivare da ApiController o qualcos'altro. Qual è la risposta che si ottiene dal server su una macchina locale? –

+0

Il mio controller è una classe pubblica. Il controller deriva da ApiContoller. Sulla mia macchina locale, ricevo un 404. È la cosa più strana. –

1

Qualunque possibilità si abbia ancora definita la route API Web predefinita ed è prima del il percorso personalizzato? Ciò farebbe fallire il tuo scenario. Le seguenti definizioni di percorso (notare l'ordine) hanno funzionato per me.

public static void Register(HttpConfiguration config) { 
    config.Routes.MapHttpRoute(
     name: "1-0Api", 
     routeTemplate: "api/1.0/{controller}/{id}", 
     defaults: new { id = RouteParameter.Optional } 
    ); 

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

Sebastiaan Dammann ha, sul suo blog, ha descritto come lo ha fatto delle versioni Web API, scrivendo la propria implementazione di IHttpControllerSelector e supportare interfacce.

http://damsteen.nl/blog/implementing-versioning-in-asp.net-web-api

Ha anche messo il codice su GitHub

https://github.com/Sebazzz/SDammann.WebApi.Versioning

e confezionato in NuGet per noi! :)

https://nuget.org/packages/SDammann.WebApi.Versioning

Mentre attuazione IHttpControllerSelector è certamente (imho) il modo giusto di fare delle versioni Web API, penso che sarebbe l'ideale se ha incluso la possibilità di versione basata sul HTTP Accept intestazione (vedi http://barelyenough.org/blog/2008/05/versioning-rest-web-services/).

Sfortunatamente il mio lato client non è in grado di lavorare con l'intestazione , quindi il suo RouteVersionedControllerSelector è l'ideale per me.

Edit: Non sono sicuro di come ho perso, ma c'è davvero una AcceptHeaderVersionedControllerSelector che può essere utilizzato per fare versioni all'ideale modo .Attualmente sto usando su un nuovo progetto, ma ha ancora some drawbacks

0

Se vogliamo il vostro primo approccio quindi aiuta a percorso e consentire noi per ottenere i dati per V1, V2 .... ma ora abbiamo fatto un esempio di V1 e V2 per il codice un controller in modo di routing sarà come di seguito:

config.Routes.MapHttpRoute(
    name: "1-0Api", 
    routeTemplate: "tables/v1/Products", 
    defaults: new { controller = "ProductsV1", id = RouteParameter.Optional } 
); 
config.Routes.MapHttpRoute(
    name: "2-0Api", 
    routeTemplate: "tables/v2/Products", 
    defaults: new { controller = "ProductsV2", id = RouteParameter.Optional } 
); 

Ma abbiamo più di 20 controller e più versioni quindi come renderlo generico.

Problemi correlati