2012-04-12 4 views
42

Utilizzo del nuovo controller Api in MVC4 e ho riscontrato un problema. Se ho i seguenti metodi:Controller Api che dichiara più di una istruzione Get

public IEnumberable<string> GetAll()

public IEnumberable<string> GetSpecific(int i)

Questo funzionerà. Tuttavia, se voglio recuperare alcuni dati differenti di tipo diverso, il valore predefinito è il metodo GetAll, anche se il $.getJSON è impostato il metodo GetAllIntegers:

public IEnumberable<int> GetAllIntergers()

(convenzioni di denominazione cattivi)

È possibile che io sia in grado di farlo?

Posso avere un solo metodo GetAll nel controller API Web?

Penso che sia più facile visualizzare ciò che sto cercando di ottenere. Ecco un frammento di codice per mostrare quello che mi piacerebbe essere in grado di fare, in un unico ApiController:

public IEnumerable<string> GetClients() 
{ // Get data 
} 

public IEnumerable<string> GetClient(int id) 
{ // Get data 
} 

public IEnumerable<string> GetStaffMember(int id) 
{ // Get data 
} 

public IEnumerable<string> GetStaffMembers() 
{ // Get data 
} 

risposta

62

Questo è tutto nel routing. Il percorso API Web predefinito è simile al seguente:

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

Con il modello di routing di default, API Web utilizza il metodo HTTP per selezionare l'azione. Di conseguenza mapperà una richiesta GET senza parametri al primo GetAll che può trovare. Per ovviare a questo è necessario definire un percorso dove il nome dell'azione è incluso:

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

Dopo di che è possibile classificare fare richieste con la seguente URL di:

  • API/yourapicontroller/GetClients
  • api/yourapicontroller/GetStaffMembers

In questo modo è possibile avere più GetAll in Controller.

Un'altra cosa importante qui è che con questo stile di routing, è necessario utilizzare gli attributi per specificare i metodi HTTP consentiti (come [HttpGet]).

C'è anche un'opzione di mescolare l'instradamento basato predefinita verbo Web API con approccio tradizionale, è molto ben descritto qui:

+0

Domanda veloce, posso instradare in questo modo e chiamare solo i miei metodi solo "Post" e li ho automaticamente accettare solo HttpPost se includo un ActionNameAttribute? – Alxandr

+0

@Alxandr Devi ancora usare AcceptVerbsAttribute (o HttpPostAttribute, HttpGetAttribute, ecc.) – tpeczek

+3

Sto riscontrando qualche problema con il routing - Posso definire più metodi "GET", ma se colpisco/api/{controller} il server dà un HTTP 500 "più azioni trovate" piuttosto che un 404. Qualche idea su come bloccarlo? Quello che mi piacerebbe è avere/api/{controller}/{id} percorso per "Get, Post, Put, Delete, ecc", quindi avere/api/{controller}/{id}/{azione} percorso per un'azione specifica, come/api/Clienti/5/Prodotti. Non funziona: tutto genera un errore "più azioni trovate". – ShadowChaser

9

Nel caso in cui qualcun altro deve affrontare questo problema. Ecco come ho risolto questo. Usa l'attributo [Route] sul tuo controller per indirizzare a un URL specifico.

[Route("api/getClient")] 
public ClientViewModel GetClient(int id) 

[Route("api/getAllClients")] 
public IEnumerable<ClientViewModel> GetClients() 
+0

collegamento attributo route per coloro che sono ancora più curiosi di sapere quale sia questo formato: https://docs.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/attribute- instradamento-in-web-api-2 – Callat