web-dev-qa-db-ja.com

MVCコントローラー:HTTP本文からJSONオブジェクトを取得しますか?

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

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

[編集]と言っても何も得られなかったjsonBodyは常にnullであることを意味したObjectとして定義するか、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 }}}
64
DeepSpace101

もしそうなら

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

その場合、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の場合、複雑なJSONデータ型のコントローラーアクションで、パラメーター名の横に[FromBody] attribを追加する必要があります。

[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();
128
DeepSpace101

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を表示しません。

7
ChunHao Tang

クラス(MyDTOClass)を定義したら、受け取るものを示すように、次のように簡単になります。

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

ジュリアスへのThx:

Json .Net Web APIの解析

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

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

1
andrew pate

私はASP.NET MVCコントローラーを取得して、 Postman .

動作させるには次のものが必要でした。

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

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

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

    postman headers

  • リクエスト本文のjson

    enter image description here

1
Eric

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

HERE 例を示しています


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


HERE は動的オブジェクトを使用した実装です

0
user1770234