web-dev-qa-db-ja.com

Fiddlerを使用してPOST Web Apiにリクエストを送信する

C#を使用して、簡単なWebApiプログラムを作成しています。 (MVCはかなりよく知っていますが、WebApiは初めてです。)次のコードサンプルに示すように、「getvendor」アクションを含むベンダーコントローラー(VendorsController.cs)が含まれています。

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

    ...
_

ルートは次のように構成されます。

_// Web API routes
config.MapHttpAttributeRoutes();

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

Fiddlerを使用してプログラムをテストしています。最初に、[FromBody]を使用せずに上記のコードを実行し、Fiddlerを使用して、POST要求を次のようなURLのユーザー名で送信します。 http:// localhost:60060/api/vendors/getvendor?username = tapuser

これはうまくいきました。 tapuserは引数としてGetVendorに渡され、アクションは期待される結果を返しました。

次に、[FromBody]を追加し、リクエスト本文に_username=tapuser_を追加しました。今回、リクエストを送信したとき、tapuserはアクションに渡されませんでした。 GetVendor()への引数はnullでした。 _{ "username": "tapuser" }_などのリクエスト本文のバリエーションを試しましたが、役に立ちません。 routeTemplateを_"api/{controller}/{action}/{id}"_に変更するなど、さまざまな方法でルートを変更しようとしました。それも助けにはなりませんでした。私は非常に単純なものを見逃していると確信していますが、私はそれを見ません。

9
Tim

リクエストボディに値を直接入れてみてください。こちらをご覧ください。 enter image description here

16
drunkcoder

今、私はいくつかのデバッグを行い、あなたが抱えていた問題を再現することができました。

私は最終的に次のことを実行することでアクションにデータを取得することができました:

最初に、ペイロードのコンテナとして機能するクラスを作成しました。

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

一致するようにアクションを更新しました

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

次に、フィドラーを使用して、テストするためにリクエストをエンドポイントに堆肥化しました。

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

ブレークポイントに到達すると、body/payloadにtapuserとしてユーザー名が入力されました。

[〜#〜] update [〜#〜]

今、上記が機能している間、私はそれがあなたの問題を解決したとは完全に確信していなかったので、私はいくつかのグーグルをし、これに遭遇

ASP.NET Web APIのパラメーターバインディング

[FromBody]を使用した次の例を示した場所

Web APIにリクエスト本文から単純型を強制的に読み取らせるには、パラメーターに[FromBody]属性を追加します。

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

この例では、Web APIはメディアタイプフォーマッタを使用して、リクエスト本文から名前の値を読み取ります。クライアントリクエストの例を次に示します。

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

"Alice"

パラメーターに[FromBody]がある場合、Web APIはContent-Typeヘッダーを使用してフォーマッターを選択します。この例では、コンテンツタイプは「application/json」であり、リクエストの本文は生のJSON文字列です(JSONオブジェクトではありません)。

メッセージ本文から読み取ることができるパラメーターは最大1つです。したがって、これは機能しません:

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

このルールの理由は、リクエストの本文が、一度しか読み取れないバッファリングされていないストリームに格納される可能性があるためです。

元の変更を元に戻して、例に従ったところ、意図したとおりに機能しました。

お役に立てれば。

1
Nkosi

リクエストの本文に「tapuser」を入力すると、一重引用符または二重引用符を使用して機能することがわかりました。引用符が答えのようです。引用符の中にtapuser以外のものを入れると、すべてが引数として渡されます。たとえば、「{username = tapuser}」は{username = tapuser}として渡されます。ご意見をお寄せいただきありがとうございます。

1
Tim