2016-06-15 75 views
17

Quali sono le differenze fondamentali di tali funzioni? Tutto quello che so sono tutti e tre i risultati in un 201, che è appropriato per una richiesta POST di successo.API POST per ASP.net Core RC2 Web - Quando utilizzare Create, CreatedAtAction, vs. CreatedAtRoute?

Seguo solo esempi che vedo online, ma non spiegano veramente perché stanno facendo quello che stanno facendo.

Dovremmo fornire un nome per il nostro GET (1 informazione da id):

[HttpGet("{id}", Name="MyStuff")] 
public async Task<IActionResult> GetAsync(int id) 
{ 
    return new ObjectResult(new MyStuff(id)); 
} 

Qual è lo scopo di nominare questo ottenere la funzione, oltre che è "probabilmente" necessario per la funzione POST qui di seguito:

[HttpPost] 
public async Task<IActionResult> PostAsync([FromBody]MyStuff myStuff) 
{ 
    // actual insertion code left out 

    return CreatedAtRoute("MyStuff", new { id = myStuff.Id }, myStuff); 
} 

noto che CreatedAtRoute ha anche un sovraccarico che non prende in nome della rotta.

C'è anche CreatedAtAction che accetta parametri simili. Perché esiste questa variante?

C'è anche Created che si aspetta un URL e l'oggetto che vogliamo restituire. Posso semplicemente usare questa variante e fornire un URL fasullo e restituire l'oggetto che voglio e farlo finire e finirlo?

Non sono sicuro del motivo per cui ci sono così tante varianti solo per poter restituire un 201 al client. Nella maggior parte dei casi, tutto ciò che voglio fare è restituire l'ID univoco "assegnato dall'app" (molto probabilmente da un database) o una versione della mia entità che ha informazioni minime.

Penso che alla fine, una risposta di 201 "dovrebbe" creare un'intestazione di posizione che abbia l'URL della risorsa appena creata, che credo che tutti e 3 e i loro sovraccarichi finiscano. Perché dovrei sempre restituire un'intestazione di posizione? I miei client JavaScript, le app native per dispositivi mobili e desktop non lo usano mai. Ad esempio, se emetto un POST HTTP, per creare dichiarazioni di fatturazione e inviarle agli utenti, quale sarebbe l'URL di tale posizione? (Le mie scuse per non aver scavato più a fondo nella storia di Internet per trovare una risposta.)

Perché creare nomi per azioni e percorsi? Qual è la differenza tra nomi di azioni e nomi di percorsi?

Sono confuso su questo, quindi ho fatto ricorso a restituire il Ok(), che restituisce 200, che è inappropriato per POST.

risposta

22

Qui ci sono alcune domande diverse che dovrebbero probabilmente essere suddivise, ma penso che questo copra la maggior parte dei tuoi problemi.

Perché creare nomi per azioni e percorsi? Qual è la differenza tra nomi di azioni e nomi di percorsi?

Prima di tutto, le azioni e le rotte sono molto diverse.

Un'azione vive su un controller. Una rotta specifica un punto finale completo costituito da un controller e un'azione e potenzialmente altri parametri del percorso aggiuntivi.

È possibile assegnare un nome a un percorso, che consente di fare riferimento alla propria applicazione.per esempio

routes.MapRoute(
    name: "MyRouteName", 
    url: "SomePrefix/{action}/{id}", 
    defaults: new { controller = "Section", action = "Index" } 
); 

La ragione di nomi di azioni sono coperte in questa domanda: Purpose of ActionName

Esso consente di avviare l'azione con un numero o includere qualsiasi carattere che .NET non consentono in un identificatore. - Il motivo più comune è che permette di avere due azioni con la stessa firma (si veda la GET/POST eliminare le azioni di qualsiasi controller ponteggi)

Quali sono le differenze fondamentali di tali funzioni?

Questi 3 funzioni tutti eseguono sostanzialmente la stessa funzione - restituisce una risposta 201 Created, con un'intestazione Location indicando l'URL per la risposta appena creato e l'oggetto stesso nel corpo. L'url dovrebbe essere l'url a cui una richiesta GET restituirebbe l'url dell'oggetto. Questo sarebbe considerato il comportamento "corretto" in un sistema RESTful.

Per l'esempio di codice postale nella domanda, in realtà si desidera utilizzare CreatedAtAction.

[HttpPost] 
public async Task<IActionResult> PostAsync([FromBody]MyStuff myStuff) 
{ 
    // actual insertion code left out 

    return CreatedAtAction("MyStuff", new { id = myStuff.Id }, myStuff); 
} 

Supponendo di avere il percorso predefinito configurato, questo aggiungerà un'intestazione posizione che punta alla MyStuff azione sullo stesso controller.

Se si voleva l'url posizione per puntare a un percorso specifico (come abbiamo definito in precedenza, è possibile utilizzare ad esempio

[HttpPost] 
public async Task<IActionResult> PostAsync([FromBody]MyStuff myStuff) 
{ 
    // actual insertion code left out 

    return CreatedAtRoute("MyRouteName", new { id = myStuff.Id }, myStuff); 
} 

Posso usare questa variante e fornire un URL fasullo e restituire l'oggetto che vuole e farlo fare e finita?

Se davvero non si vuole usare un CreatedResult, è possibile utilizzare un semplice StatusCodeResult, che restituirà una 201, senza intestazione e corpo Location.

01.235.
[HttpPost] 
public async Task<IActionResult> PostAsync([FromBody]MyStuff myStuff) 
{ 
    // actual insertion code left out 

    return StatusCode(201); 
} 
+0

Non sono sicuro di .NET Core, ma esiste ancora il metodo 'Content (HttpStatusCode, T content)' per restituire sia un codice di stato che un contenuto? Questo dovrebbe consentire di restituire 201 insieme all'oggetto appena creato, senza includere l'intestazione 'Location'. – afrazier

+1

Quel sovraccarico non sembra più esistere, ma c'è in realtà un sovraccarico per StatusCode che è possibile utilizzare in modo simile: 'StatusCode (int httpStatusCode, valore dell'oggetto)' – Sock

+1

Sembra che '[HttpGet (" {id} " , Name = "GetUser", Order = 0)] 'modo di creare un percorso non sembra funzionare con CreatedAtRoute() – Crob