73

MVC(MVC4)アプリケーションがあり、サードパーティから特定のURL( " http://server.com/events/ ")にJSONイベントがPOSTされる場合があります。JSONイベントはHTTPPOSTの本文にあり、本文は厳密にJSONです(Content-Type: application/json文字列フィールドにJSONが含まれるフォームポストではありません)。

コントローラの本体内でJSON本体を受け取るにはどうすればよいですか?次のことを試しましたが、何も得られませんでした

[編集] :何も得られなかったと言ったとき、私が定義したObjectかどうかに関係なく、jsonBodyは常にnullであることを意味しましたstring

[HttpPost]
// this maps to http://server.com/events/
// why is jsonBody always null ?!
public ActionResult Index(int? id, string jsonBody)
{
    // Do stuff here
}

強く型付けされた入力パラメーターを使用してメソッドを宣言すると、MVCが解析とフィルタリング全体を実行することを知っていることに注意してください。

// this tested to work, jsonBody has valid json data 
// that I can deserialize using JSON.net
public ActionResult Index(int? id, ClassType847 jsonBody) { ... }

ただし、取得するJSONは非常に多様であるため、JSONバリアントごとに数百の異なるクラスを定義(および維持)する必要はありません。

私は次のcurlコマンドでこれをテストしています(ここではJSONの1つのバリアントを使用)

curl -i -H "Host: localhost" -H "Content-Type: application/json" -X POST http://localhost/events/ -d '{ "created": 1326853478, "data": { "object": { "num_of_errors": 123, "fail_count": 3 }}}
4

5 に答える 5

157

どうやら

  • Content-Type: application/json
  • POST本体がコントローラの入力オブジェクトクラスに緊密にバインドされていない場合

その場合、MVCはPOST本体を特定のクラスに実際にバインドしません。また、POST本文をActionResultのパラメーターとしてフェッチすることもできません(別の回答で提案されています)。けっこうだ。リクエストストリームから自分でフェッチして処理する必要があります。

[HttpPost]
public ActionResult Index(int? id)
{
    Stream req = Request.InputStream;
    req.Seek(0, System.IO.SeekOrigin.Begin);
    string json = new StreamReader(req).ReadToEnd();

    InputClass input = null;
    try
    {
        // assuming JSON.net/Newtonsoft library from http://json.codeplex.com/
        input = JsonConvert.DeserializeObject<InputClass>(json)
    }

    catch (Exception ex)
    {
        // Try and handle malformed POST body
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }

    //do stuff

}

アップデート:

Asp.Net Coreの場合[FromBody]、複雑なJSONデータ型のコントローラーアクションで、パラメーター名の横に属性を追加する必要があります。

[HttpPost]
public ActionResult JsonAction([FromBody]Customer c)

また、リクエスト本文に文字列としてアクセスして自分で解析する場合は、次Request.Bodyの代わりに使用する必要がありRequest.InputStreamます。

Stream req = Request.Body;
req.Seek(0, System.IO.SeekOrigin.Begin);
string json = new StreamReader(req).ReadToEnd();
于 2012-10-29T06:26:34.893 に答える
7

Request.Formデータを取得するために使用する

コントローラ:

    [HttpPost]
    public ActionResult Index(int? id)
    {
        string jsonData= Request.Form[0]; // The data from the POST
    }

これを書いて試してみます

意見:

<input type="button" value="post" id="btnPost" />

<script type="text/javascript">
    $(function () {
        var test = {
            number: 456,
            name: "Ryu"
        }
        $("#btnPost").click(function () {
            $.post('@Url.Action("Index", "Home")', JSON.stringify(test));
        });
    });
</script>

書き込みRequest.Form[0]またはRequest.Params[0]コントローラでデータを取得できます。

私は視野に入れていません<form> tag

于 2012-10-24T05:17:27.980 に答える
2

私は、ASP.NET MVCコントローラーに、 Postmanを使用して送信したモデルを解析させようとしています。

それを機能させるには、次のものが必要でした。

  • コントローラーアクション

    [HttpPost]
    [PermitAllUsers]
    [Route("Models")]
    public JsonResult InsertOrUpdateModels(Model entities)
    {
        // ...
        return Json(response, JsonRequestBehavior.AllowGet);
    }
    
  • モデルクラス

    public class Model
    {
        public string Test { get; set; }
        // ...
    }
    
  • Postmanのリクエストのヘッダー、具体的にはContent-Type

    postmanヘッダー

  • リクエスト本文のjson

    ここに画像の説明を入力してください

于 2019-07-17T17:57:24.523 に答える
1

受け取ることを期待するものを示すクラス(MyDTOClass)を定義したら、それは次のように単純である必要があります...

public ActionResult Post([FromBody]MyDTOClass inputData){
 ... do something with input data ...
}

ジュリアスへのThx:

Json .NetWebApiの解析

リクエストがhttpヘッダーで送信されていることを確認してください。

コンテンツタイプ:application / json

于 2017-07-13T14:43:45.573 に答える
0

json文字列をのパラメータとして取得し、ActionResultその後、JSON.Netを使用してシリアル化できます。

ここに例が示されています


シリアル化された形式でコントローラーアクションのパラメーターとして受け取るには、カスタムモデルバインダーまたはアクションフィルター(OnActionExecuting)を記述して、json文字列が好みのモデルにシリアル化されてコントローラー内で使用できるようにする必要があります。使用するボディ。


ここに動的オブジェクトを使用した実装があります

于 2012-10-24T05:26:49.863 に答える