2012-04-12 12 views
42

Używanie nowego kontrolera Api w MVC4 i znalazłem problem. Jeśli mam następujące metody:Kontroler Api deklarujący więcej niż jedną instrukcję Pobierz

public IEnumberable<string> GetAll()

public IEnumberable<string> GetSpecific(int i)

to będzie działać. Jednakże, jeśli chcę odzyskać kilka różnych danych innego typu, to domyślnie metody GetAll, choć $.getJSON ustawiony jest na metodzie GetAllIntegers:

public IEnumberable<int> GetAllIntergers()

(złe nazewnictwa)

Czy mogę to zrobić?

Czy mogę mieć tylko jedną metodę GetAll w kontrolerze Web API?

Myślę, że łatwiej jest wyobrazić sobie, co próbuję osiągnąć. Oto fragment kodu, aby pokazać, co chciałabym być w stanie wykonać w jednym 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 
} 

Odpowiedz

62

To wszystko w routingu. Domyślna trasa Web API wygląda tak:

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

Przy domyślnym szablonie routingu, Web API używa metody HTTP do wyboru akcji. W rezultacie mapuje żądanie GET bez parametrów, które może najpierw znaleźć. W celu obejścia tego trzeba określić trasy, gdzie nazwa działania obejmowały:

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

Po tym można gwiazda podejmowania wnioski z następujących adresów URL:

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

W ten sposób można mieć wiele kontrolek GetAll.

Jeszcze jedną ważną rzeczą jest to, że w przypadku tego stylu routingu należy użyć atrybutów, aby określić dozwolone metody HTTP (np. [HttpGet]).

Istnieje również możliwość mieszania routing oparty domyślny Web API czasownik z tradycyjnego podejścia, jest bardzo dobrze opisane tutaj:

+0

Szybkie pytanie, czy mogę tak prowadzić i nadal nazywam moje metody tylko "Opublikuj" i czy automatycznie akceptują one tylko HttpPost, jeśli dołączę AkcjaNazwisko? – Alxandr

+0

@Alxandr Nadal będziesz musiał używać AcceptVerbsAttribute (lub HttpPostAttribute, HttpGetAttribute itp.) – tpeczek

+3

Mam pewne problemy z routingiem - mogę zdefiniować wiele metod "GET", ale jeśli uderzę/api/{controller} serwer daje HTTP 500 "wiele akcji znalezionych" zamiast 404. Dowolny pomysł, jak to zablokować? Chciałbym mieć/api/{controller}/{id} trasę do "Get, Post, Put, Delete, etc", a następnie mam/api/{controller}/{id}/{action} trasę do konkretne działanie, takie jak/api/Customers/5/Products. Nie działa - wszystko daje błąd "znaleziono wiele działań". – ShadowChaser

9

W przypadku gdy ktoś inny stoi ten problem. Oto jak to rozwiązałem. Użyj atrybutu [Trasa] na kontrolerze, aby skierować do określonego adresu URL.

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

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

link atrybutów trasy dla jeszcze bardziej ciekawych tego formatu: https://docs.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/attribute- routing-in-web-api-2 – Callat