2014-11-22 13 views
8

Ho questa azione di controllo:WebApi POST funziona senza [FromBody]?

[HttpPost] 
[ActionName("aaa")] 
public HttpResponseMessage aaa(Z z) //notice - no [FromBody] 
{ 
    return Request.CreateResponse(HttpStatusCode.OK, 1); 
} 

Dove Z è:

public class Z 
{ 
    public string a { get; set; } 
} 

Ma quando inserisco via violinista:

POST http://localhost:11485/api/profiles/aaa HTTP/1.1 
Content-Type: application/x-www-form-urlencoded; charset=UTF-8 
Host: localhost:11485 
Content-Length: 3 
Accept-Encoding: gzip, deflate 
Accept-Language: en-US,en;q=0.8,he;q=0.6 
Cache-Control: no-cache 
Connection: keep-alive 

a=1 

posso effettivamente vedere che sta lavorando:

enter image description here

Domanda:

In caso affermativo, come si lavora senza il [FromBody] attributo? e ho ancora bisogno/non scrivere questo attributo?

Inoltre, qual è lo scenario in cui non si scrive questo attributo - causerà problemi?

+0

Interessante domanda. Ho trovato alcune informazioni qui: http://encosia.com/using-jquery-to-post-frombody-parameters-to-web-api/ –

risposta

12

Il collegamento è diverso per MVC e Web API. Per impostazione predefinita, l'API Web ASP.NET lega tipi complessi dal corpo del messaggio di richiesta e tipi semplici dall'URI, dalla stringa di query, ecc. Poiché hai specificato Z, che è una classe (tipo complesso), popola il parametro del metodo di azione dal corpo senza devi specificare [FromBody]. D'altra parte, se la tua richiesta è http://localhost:11485/api/profiles/aaa?a=1 senza un corpo, NON legherà automaticamente i tuoi parametri complessi. In tal caso, sarà necessario specificare [FromUri] in questo modo: public HttpResponseMessage aaa([FromUri]Z z).

D'altra parte, supponiamo che il tuo metodo di azione sia public HttpResponseMessage aaa(string a). Ora abbiamo string, che è un tipo semplice. In questo caso, http://localhost:11485/api/profiles/aaa?a=1 senza un corpo del messaggio consentirà all'API Web di associare correttamente il parametro senza dover specificare [FromUri]. Ora, se si desidera eseguire il binding dal corpo in questo caso, è necessario specificare public HttpResponseMessage aaa([FromBody]string a). Naturalmente, per questo corpo deve essere =1, per application/x-www-form-urlencoded, senza il nome della chiave di a.

Bottom line: il parametro (tipo semplice o tipo complesso) determina il modo in cui le API Web si collegano. Per farlo funzionare in modo diverso dal comportamento predefinito, è necessario specificare tramite FromUri o FromBody.

PS. Qualunque cosa ho menzionato sopra vale solo per la buona vecchia API Web ASP.NET (incluso 2). In ASP.NET 5.0 a.k.a ASP.NET vNext o ASP.NET MVC 6.0, MVC e Web API sono stati unificati. Per poter associare un tipo complesso dal corpo, è necessario specificare [FromBody].

+1

Spiegazione molto dettagliata. Grazie, Badri. Come nota a margine, voglio davvero sapere cosa pensava MS quando permettevano solo il pattern '= 1', quando si scrivevano i tipi semplici .... voglio dire - non mi interessa, ma devo dire ai consumatori di inviare solo = 1. E questo è molto (!) Male –

+0

Bene, il corpo viene letto solo una volta e associato a un parametro nella sua interezza. Ad esempio, non puoi avere metà del corpo vincolato a un parametro e riposare in un altro. Quando si collega un corpo a un tipo semplice, non è necessario affatto il tasto, poiché può essere solo il parametro a cui è associato. Ma è un po 'di confusione però. – Badri

Problemi correlati