2013-08-05 24 views
9

Miejmy model testowy.Obsługa GET * i * POST w WebApi

public class TestRequestModel 
{ 
    public string Text { get; set; } 
    public int Number { get; set; } 
} 

Chciałbym tę usługę, aby móc przyjąć następujące wnioski:

  • GET/Test Number = 1234 & Text = myText
  • POST/test z nagłówka? : Content-Type: application/x-www-form-urlencoded i treść: Numer = 1234 & Text = MyText
  • POST/test z nagłówkiem: Content-Type: application/json i ciała: { "Text": "Pod", "Number": 9876}

Trasy są skonfigurowane w następujący sposób:

_config.Routes.MapHttpRoute(
    "DefaultPost", "/{controller}/{action}", 
    new { action = "Post" }, 
    new { httpMethod = new HttpMethodConstraint(HttpMethod.Post) }); 

_config.Routes.MapHttpRoute(
    "The rest", "/{controller}/{action}", 
    defaults: new { action = "Get" }); 

Mój kontroler wygląda następująco:

public class TestController : ApiController 
{ 
    [HttpGet] 
    public TestResponseModel Get([FromUri] TestRequestModel model) 
    { 
     return Do(model); 
    } 

    [HttpPost] 
    public TestResponseModel Post([FromBody] TestRequestModel model) 
    { 
     return Do(model); 
    } 
    (...) 

Wygląda to na akceptowalną ilość kodu płyty kotła, ale nadal chciałbym tego uniknąć, jeśli to możliwe.

Posiadanie dodatkowej trasy również nie jest idealne. Mam obawy przed trasami MVC/WebAPi i uważam, że są złe.

Czy istnieje sposób na uniknięcie dwóch metod i/lub trasy domyślnej DefaultPost?

+0

Myślę, że dodałeś za dużo kodu, spójrz na domyślny projekt, który zostanie wygenerowany. Nie potrzebujesz swoich atrybutów ani specjalnych dróg, by robić to, co robisz.Również różne czasowniki oznaczają różne intencje, 'GET' służy do uzyskiwania dostępu do danych, podczas gdy' POST' służy do tworzenia nowych danych. – Matthew

Odpowiedz

8

To, o co prosisz, nie jest typowe dla interfejsu ASP.NET Web API. W ASP.NET MVC często stosuje się tę samą metodę działania, która obsługuje początkowy GET i kolejny post (POST). ASP.NET Web API jest przeznaczony do budowania usług HTTP, a GET służy do pobierania zasobów bez zmieniania czegokolwiek w systemie, podczas gdy POST służy do tworzenia nowego zasobu, jak wskazał Matthew.

W każdym razie nie jest niemożliwe posiadanie jednej metody działania w Web API, aby to osiągnąć. Ale chcesz, aby ta sama metoda działania nie tylko obsługiwała GET i POST, ale także wiązała model i wiązała formatator. Powiązanie modelu (podobne do MVC) wiąże identyfikator URI żądania, ciąg zapytania, itp. Z parametrami, podczas gdy powiązanie formatera (unikalne dla interfejsu API WWW) wiąże zawartość treści z parametrem. Domyślnie typy proste są powiązane z identyfikatorem URI, ciągiem zapytania i złożonymi typami z treści głównej. Tak więc, jeśli masz metodę działania z parametrami string text, int number, TestRequestModel model, możesz mieć powiązanie web API z URI lub treścią iw tym przypadku musisz sprawdzić, co nie jest puste i użyć tego. Ale takie rozwiązanie będzie wyglądało raczej jak włamanie, niestety. Lub jeśli chcesz, aby ten sam typ złożony był wypełniany zarówno z adresu URI/ciągu zapytania, jak i treści, musisz napisać własny parametr, który sprawdzi części żądania i odpowiednio zapełni ten parametr.

Nie trzeba również mieć dwóch odwzorowań trasy. Domyślny taki jak to zrobi.

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