web-dev-qa-db-ja.com

FromBody文字列パラメーターがnullを与えています

これはおそらく非常に基本的なことですが、どこに問題があるのか​​わからないのです。

POSTの本文から文字列を取得しようとしていますが、「jsonString」はnullとしてのみ表示されます。また、モデルの使用を避けたいのですが、これはおそらく不可能です。 PostManでヒットしているコードは、次のチャンクです。

[Route("Edit/Test")]
[HttpPost]
public void Test(int id, [FromBody] string jsonString)
{
    ...
}

多分それは私が郵便配達員で間違ってやっていることですが、私は本文の値セクションで「= test」(このトピックについての他の質問で見られるように)を使用しようとしています-x-www-form-urlencodedセクションjsonStringなどのキー。また、raw-textおよびraw-text/plainを使用してみました。 IDを取得するので、URLが正しいことがわかります。これに関するヘルプは大歓迎です。

現在、PostManは次のように設定されています。

POST http://localhost:8000/Edit/Test?id=111
key = id  value = 111
Body - x-www-form-urlencoded
key = jsonString  value = "=test"
27
Robert Prine

JsonStringパラメーターを[FromBody]で宣言することにより、ASP.NET Coreに入力フォーマッターを使用して、提供されたJSON(またはXML)をモデルにバインドするように指示します。したがって、単純なモデルクラスを提供する場合、テストは機能するはずです。

public class MyModel
{
    public string Key {get; set;}
}

[Route("Edit/Test")]
[HttpPost]
public void Test(int id, [FromBody] MyModel model)
{
    ... model.Key....
}

と送信されたJSONのような

{
    key: "value"
}

もちろん、モデルのバインディングをスキップして、コントローラーのHttpContext.Requestにアクセスすることで、提供されたデータを直接取得できます。 HttpContext.Request.Bodyプロパティはコンテンツストリームを提供するか、HttpContext.Request.Formsを介してフォームデータにアクセスできます。

個人的には、型の安全性のためにモデルのバインディングを好みます。

37
Ralf Bönning

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

[FromBody]を使用する

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

[Route("Edit/Test")]
[HttpPost]
public IHttpActionResult Test(int id, [FromBody] string jsonString) { ... }

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

POST http://localhost:8000/Edit/Test?id=111 HTTP/1.1
User-Agent: Fiddler
Host: localhost:8000
Content-Type: application/json
Content-Length: 6

"test"

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

上記の例では、データが本体で正しい形式で提供されている場合、モデルは必要ありません。

URLエンコードの場合、リクエストは次のようになります

POST http://localhost:8000/Edit/Test?id=111 HTTP/1.1
User-Agent: Fiddler
Host: localhost:8000
Content-Type: application/x-www-form-urlencoded
Content-Length: 5

=test
40
Nkosi

[[FromBody]]属性がある場合、送信される文字列は、生の文字列ではなく、JSON文字列である必要があります。

"test"

https://weblog.west-wind.com/posts/2017/Sep/14/Accepting-Raw-Request-Body-Content-in-ASPNET-Core-API-Controllers に基づく

同様の回答 asp.net Web APIでFromBodyを使用する場合、文字列値は空です

14

あなたは正しい軌道に乗っています。

ヘッダーセット

Content-Type: application/x-www-form-urlencoded

POSTリクエストの本文は=testでなければならず、他には何もありません。不明/可変文字列の場合、入力文字で誤ってエスケープしないように、値をURLエンコードする必要があります。


ASP.NET Web ApiアプリケーションへのPOST文字列-nullを返します も参照してください。

6
Igor

私の場合、JSON.stringify(bodyStuff)を使用するのを忘れていました。

4
Eugene

私はこの答えがちょっと古くて、すでに問題を解決している非常に良い答えがあることを知っています。

問題を拡大するために、最後の4時間または5時間で私を夢中にさせたもう1つのことを述べたいと思います。


非常に非常に非常にモデルクラスのプロパティでset属性が有効になっていることが重要です。


これWILL NOT動作(パラメーターはまだnull):

/* Action code */
[HttpPost]
public Weird NOURLAuthenticate([FromBody] Weird form) {
    return form;
}
/* Model class code */
public class Weird {
    public string UserId {get;}
    public string UserPwd {get;}
}

これはWILL work:

/* Action code */
[HttpPost]
public Weird NOURLAuthenticate([FromBody] Weird form) {
    return form;
}
/* Model class code */
public class Weird {
    public string UserId {get; set;}
    public string UserPwd {get; set;}
}
2

生のJSONで文字列を投稿し、二重引用符を忘れないでください!

enter image description here

0
Mohammad Alqerm

1時間の苦労の末、ようやく機能するようになりました。

これにより、nullの問題が削除され、JSON key1の値value1が一般的な方法(モデルバインディングなし)で取得されます。

新しいWebApi 2アプリケーションの例:

郵便配達員(正確には以下のように見えます):

POST    http://localhost:61402/api/values   [Send]

              Body
                   (*) raw             JSON (application/json) v

"{  \"key1\": \"value1\" }"

上記のポート61402またはurl / api/valuesは、異なる場合があります。

ValuesController.cs

using Newtonsoft.Json;
// ..

// POST api/values
[HttpPost]
public object Post([FromBody]string jsonString)
{
    // add reference to Newtonsoft.Json
    //  using Newtonsoft.Json;

    // jsonString to myJsonObj
    var myJsonObj = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(jsonString);

    // value1 is myJsonObj[key1]
    var valueOfkey1 = myJsonObj["key1"];

    return myJsonObj;
}

サブキーがある場合、クラスへのモデルバインディングが必要かどうか、またはサブキーでDeserializeObjectが機能するかどうかはわかりません。

Googleをいじくり回してStack Overflowで間違ったコードを試してみた後、([FromBody]文字列モデル)を([FromBody]オブジェクトモデル)に変更すると、.NET 4.0を使用していないのではないかと思いました古いけど...

0