2016-06-15 4 views
17

Was sind die grundlegenden Unterschiede dieser Funktionen? Alles was ich weiß sind alle drei Ergebnisse in einer 201, die für eine erfolgreiche POST-Anfrage geeignet ist.ASP.net Core RC2-Web-API POST - Wann Create, CreatedAtAction, vs CreatedAtRoute verwenden?

Ich folge nur Beispielen, die ich online sehe, aber sie erklären nicht wirklich, warum sie tun, was sie tun.

Wir sollten einen Namen für unseren GET (1 Datensatz von id) zur Verfügung zu stellen:

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

Was ist der Zweck dieser Funktion erhalten zu benennen ist, außer, dass es „wahrscheinlich“, die für die POST-Funktion unten: ich

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

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

feststellen, dass CreatedAtRoute auch eine Überlastung hat, die nicht in den Namen der Route nimmt.

Es gibt auch CreatedAtAction, die ähnliche Parameter aufnimmt. Warum existiert diese Variante?

Es gibt auch Created, die eine URL und das Objekt erwartet, das wir zurückgeben möchten. Kann ich einfach diese Variante verwenden und eine gefälschte URL bereitstellen und das Objekt, das ich möchte, zurückgeben und fertig machen?

Ich bin mir nicht sicher, warum es so viele Varianten gibt, nur um eine 201 an den Client zurückgeben zu können. In den meisten Fällen möchte ich nur die "app-assigned" (höchstwahrscheinlich aus einer Datenbank) eindeutige ID oder eine Version meiner Entität mit minimalen Informationen zurückgeben.

Ich denke, dass eine Antwort 201 schließlich "sollte" einen Standort-Header erstellen, der die URL der neu erstellten Ressource hat, von der ich glaube, dass alle 3 und ihre Überladungen am Ende tun. Warum sollte ich immer einen Standort-Header zurückgeben? Meine JavaScript-Clients, nativen Mobilgeräte und Desktop-Apps verwenden sie nie. Wenn ich beispielsweise einen HTTP-POST ausstelle, um Abrechnungen zu erstellen und sie an die Benutzer zu senden, was wäre eine solche URL? (Ich entschuldige mich dafür, dass ich nicht tiefer in die Geschichte des Internets eindringe, um eine Antwort dafür zu finden.)

Warum Namen für Aktionen und Routen erstellen? Was ist der Unterschied zwischen Aktionsnamen und Routennamen?

Ich bin darüber verwirrt, so dass ich die Ok() zurückgegeben, die 200 zurückgibt, die für POST ungeeignet ist.

Antwort

22

Es gibt ein paar verschiedene Fragen hier, die wahrscheinlich aufgeteilt werden sollten, aber ich denke, das deckt den Großteil Ihrer Probleme ab.

Warum Namen für Aktionen und Routen erstellen? Was ist der Unterschied zwischen Aktionsnamen und Routennamen?

Zunächst sind Aktionen und Routen sehr unterschiedlich.

Eine Aktion läuft auf einem Controller. Eine Route gibt einen vollständigen Endpunkt an, der aus einem Controller, einer Aktion und möglicherweise zusätzlichen anderen Routenparametern besteht.

Sie können einer Route einen Namen geben, mit dem Sie in Ihrer Anwendung darauf verweisen können.zum Beispiel

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

Der Grund für die Aktionsnamen sind in dieser Frage behandelt: Purpose of ActionName

Es Ihnen Ihre Aktion mit einer Reihe starten kann oder ein beliebiges Zeichen enthalten, die in einer .net nicht erlaubt Kennung. - Der häufigste Grund ist es Ihnen erlaubt, zwei Aktionen mit der gleichen Signatur (siehe die GET/POST-Aktionen von jedem eingerüstete Controller löschen)

Was sind die grundlegenden Unterschiede dieser Funktionen sind?

Diese drei Funktionen alle führen im Wesentlichen die gleiche Funktion - eine 201 Created Antwort zurückgibt, mit einem Location Header für das neu erstellte Antwort auf die URL verweist, und das Objekt selbst in den Körper. Die URL sollte die URL sein, bei der eine GET-Anforderung die Objekt-URL zurückgeben würde. Dies würde als das "richtige" Verhalten in einem REST-System angesehen werden.

Für das Beispiel Postleitzahl in Ihrer Frage, Sie möchten tatsächlich CreatedAtAction verwenden.

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

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

Angenommen, Sie die Standardroute konfiguriert haben, wird dies einen Location-Header hinzufügen, auf die MyStuff Aktion auf demselben Controller zeigt.

Wenn Sie den Speicherort URL verweist auf eine bestimmte Route wollte (wie wir früher definiert sind, könnten Sie zB

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

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

Kann ich nur diese Variante verwenden und eine gefälschte URL zur Verfügung stellen und das Objekt Ich kehre wollen und bekommen es getan und über mit?

Wenn Sie wirklich eine CreatedResult nicht verwenden möchten, können Sie eine einfache StatusCodeResult verwenden können, die eine 201, ohne die Location Kopf- oder Körper zurück.

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

    return StatusCode(201); 
} 
+0

Ich bin nicht sicher über .NET Core, aber existiert die 'Content (HttpStatusCode, T content)' Methode immer noch, um sowohl einen Statuscode als auch Inhalt zurückzugeben? Das sollte es ermöglichen, 201 zusammen mit dem neu erzeugten Objekt zurückzugeben, ohne den "Location" -Header einzubeziehen. – afrazier

+1

Diese Überladung scheint nicht mehr zu existieren, aber es gibt tatsächlich eine Überladung für StatusCode, die Sie ähnlich verwenden können: 'StatusCode (int httpStatusCode, Objektwert)' – Sock

+1

Es scheint, dass die '[HttpGet (" {id} " , Name = "GetUser", Order = 0)] 'Methode zum Erstellen einer Route scheint nicht mit CreatedAtRoute() zu funktionieren – Crob

Verwandte Themen