webentwicklung-frage-antwort-db.com.de

Verwenden von Fiddler zum Senden einer POST Anfrage an Web Api

Ich schreibe ein einfaches WebApi-Programm mit C #. (Ich kenne MVC ziemlich gut, aber ich bin neu bei WebApi.) Es enthält einen VendorsController (VendorsController.cs), der eine "getvendor" -Aktion enthält, wie im folgenden Codebeispiel gezeigt:

[RoutePrefix("api/vendors")]
public class VendorsController : ApiController
{
    [Route("getvendor"), HttpPost]
    public TAPUser GetVendor([FromBody] string username)
    {
        Int32 userid = -1;

    ...

Die Routen sind wie folgt konfiguriert:

// Web API routes
config.MapHttpAttributeRoutes();

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

Ich benutze Fiddler, um das Programm zu testen. Zuerst habe ich den obigen Code ohne [FromBody] ausgeführt und mit Fiddler eine POST - Anforderung mit dem Benutzernamen in der URL wie folgt gesendet: http: // localhost: 60060/api/vendors/getvendor? username = tapuser

Das hat gut funktioniert. tapuser wurde als Argument an GetVendor übergeben und die Aktion gab das erwartete Ergebnis zurück.

Als Nächstes fügte ich [FromBody] hinzu und fügte username = tapuser in den Anforderungstext ein. Als ich diesmal die Anfrage abschickte, wurde tapuser nicht an die Aktion übergeben. Das Argument für GetVendor () war null. Ich habe Variationen des Anforderungshauptteils wie {"username": "tapuser"} ausprobiert, aber es hilft nicht. Ich habe auch versucht, die Route auf verschiedene Weise zu ändern, z. B. indem Sie routeTemplate in "api/{controller}/{action}/{id}" ändern. Das hat auch nicht geholfen. Ich bin sicher, ich vermisse etwas sehr einfaches, aber ich sehe es einfach nicht.

7
Tim

Versuchen Sie, Ihren Wert direkt in den Anforderungstext einzufügen. Sieh dir das an.  enter image description here

14
drunkcoder

Jetzt habe ich etwas debuggen können und konnte das Problem, das Sie hatten, neu erstellen. 

Ich war schließlich in der Lage, die Daten für die Aktion zu erhalten, indem ich Folgendes tat:

Zuerst habe ich eine Klasse erstellt, die als Container für die Nutzlast dient.

public class body {
    public string username { get; set; }
}

und aktualisiert die Aktion entsprechend

[Route("getvendor"), HttpPost]
public TAPUser GetVendor([FromBody] body payload) {...}

Dann mit Fiddler kompostierte ich die Anfrage an den Endpunkt zum Testen.

POST  http://localhost:60060/api/vendors/getvendor HTTP/1.1
User-Agent: Fiddler
Host: localhost:60060
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Content-Length: 16

username=tapuser

Wenn mein Haltepunkt getroffen wurde, wurde die Body/Payload mit dem Benutzernamen als tapuser aufgefüllt.

UPDATE

Nun, während die oben genannten Dinge funktionierten, war ich mir nicht ganz sicher, ob es Ihr Problem gelöst hat, also habe ich googeln und bin auf dieses Problem gestoßen 

Parameterbindung in ASP.NET-Web-API

Wo das folgende Beispiel mit [FromBody] zeigte

Fügen Sie das .__ hinzu, um die Web-API zu zwingen, einen einfachen Typ aus dem Anfragetext zu lesen. [FromBody] -Attribut für den Parameter:

public HttpResponseMessage Post([FromBody] string name) { ... }

In diesem Beispiel verwendet das Web-API einen Medientyp-Formatierer, um die .__-Datei zu lesen. Wert des Namens aus dem Anforderungstext. Hier ist ein Beispielclient anfordern.

POST http://localhost:5076/api/values HTTP/1.1
User-Agent: Fiddler
Host: localhost:5076
Content-Type: application/json
Content-Length: 7

"Alice"

Wenn ein Parameter über [FromBody] verfügt, verwendet die Web-API den Content-Type-Header einen Formatierer auswählen. In diesem Beispiel lautet der Inhaltstyp "application/json" und der Anforderungstext ist eine unformatierte JSON-Zeichenfolge (kein JSON-Objekt).

Es darf höchstens ein Parameter aus dem Nachrichtentext lesen. So das wird nicht funktionieren:

// Caution: Will not work!    
public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }

Der Grund für diese Regel ist, dass der Anforderungstext möglicherweise in einer .__ gespeichert wird. nicht gepufferter Stream, der nur einmal gelesen werden kann.

Als ich meine ursprünglichen Änderungen zurücksetzte und dem Beispiel folgte, funktionierte es wie beabsichtigt.

Hoffe das hilft.

1
Nkosi

Ich habe herausgefunden, dass es funktioniert, wenn ich 'tapuser' in den Anforderungstext mit einfachen oder doppelten Anführungszeichen einsetze. Die Zitate scheinen die Antwort zu sein. Wenn ich etwas anderes als tapuser in die Anführungszeichen stecke, wird das Ganze als Argument übergeben. Beispielsweise wird "{Benutzername = Tapuser}" als {Benutzername = Tapuser} übergeben. Vielen Dank an alle für Ihre Beiträge.

1
Tim