web-dev-qa-db-ja.com

jQueryを介したJSONデータのASP .NET MVC 4コントローラーアクションへの投稿

複雑なJSONオブジェクトをMVC 4コントローラーアクションに渡そうとすると問題が発生します。 JSONコンテンツは可変であるため、MVCがJSONの個々のプロパティ/要素をアクションメソッドのパラメーターリストのパラメーターにマッピングしないようにします。コントローラーアクションで単一のJSON文字列パラメーターとしてデータを取得するだけです。

アクションメソッドのシグネチャは次のとおりです。

    [HttpPost]
    [ValidateInput(false)]
    public string ConvertLogInfoToXml(string jsonOfLog)

そして、私のブラウザーからJSONデータを投稿しようとしています。

    data = {prop: 1, myArray: [1, "two", 3]}; 
    //'data' is much more complicated in my real application
    json = {jsonOfLog: data};

    $.ajax({
        type: 'POST',
        url: "Home/ConvertLogInfoToXml",
        data: JSON.stringify(json),
        success: function (returnPayload) {
            console && console.log ("request succeeded");
        },
        error: function (xhr, ajaxOptions, thrownError) {
            console && console.log ("request failed");
        },
        dataType: "xml",
        contentType: "application/json",            
        processData: false,
        async: false
    });

ConvertLogInfoToXMLメソッドの先頭でブレークポイントに到達すると、jsonOfLogはnullになります。

JavaScriptで設定されている「json」変数を変更して、jsonOfLogプロパティが単純な文字列になるようにします。 :

json = { jsonOfLog: "simple string" };

convertLogInfoToXMLメソッドの先頭にあるブレークポイントにヒットすると、jsonOfLogは文字列の値(「単純な文字列」など)になります。

アクションメソッドのjsonOfLogパラメーターの型をオブジェクト型に変更しようとしました。

    [HttpPost]
    [ValidateInput(false)]
    public string ConvertLogInfoToXml(object jsonOfLog)

現在、元のJavaScriptコード(より複雑な「データ」オブジェクトを渡している)で、jsonOfLogは{object}の値を取得します。しかし、デバッガはウォッチウィンドウにこれ以上詳細を表示せず、この変数を操作するために使用できるメソッドがわかりません。

渡されたデータが文字列化された複雑なオブジェクトであるMVCコントローラーにJSONデータを渡すにはどうすればよいですか?

ありがとう、ノートル

28
Notre

問題は、dataTypedataパラメーターの形式です。これをサンドボックスでテストしたところ、次のように動作します。

C#

    [HttpPost]
    public string ConvertLogInfoToXml(string jsonOfLog)
    {
        return Convert.ToString(jsonOfLog);
    }

javascript

<input type="button" onclick="test()"/>

    <script type="text/javascript">

        function test() {
            data = { prop: 1, myArray: [1, "two", 3] };
            //'data' is much more complicated in my real application
            var jsonOfLog = JSON.stringify(data);

            $.ajax({
                type: 'POST',
                dataType: 'text',
                url: "Home/ConvertLogInfoToXml",
                data: "jsonOfLog=" + jsonOfLog,
                success: function (returnPayload) {
                    console && console.log("request succeeded");
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    console && console.log("request failed");
                },

                processData: false,
                async: false
            });
        }

    </script>

dataに特に注意してください。テキストを送信するときは、パラメーターの名前と一致する変数を送信する必要があります。それはきれいではありませんが、あなたの切望されている書式なし文字列を取得します。

これを実行すると、jsonOfLogはサーバー関数で次のようになります。

    jsonOfLog   "{\"prop\":1,\"myArray\":[1,\"two\",3]}"    string

HTTP POSTヘッダー:

Key Value
Request POST /Home/ConvertLogInfoToXml HTTP/1.1
Accept  text/plain, */*; q=0.01
Content-Type    application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With    XMLHttpRequest
Referer http://localhost:50189/
Accept-Language en-US
Accept-Encoding gzip, deflate
User-Agent  Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)
Host    localhost:50189
Content-Length  42
DNT 1
Connection  Keep-Alive
Cache-Control   no-cache
Cookie  EnableSSOUser=admin

HTTP POST body:

jsonOfLog={"prop":1,"myArray":[1,"two",3]}

応答ヘッダー:

Key Value
Cache-Control   private
Content-Type    text/html; charset=utf-8
Date    Fri, 28 Jun 2013 18:49:24 GMT
Response    HTTP/1.1 200 OK
Server  Microsoft-IIS/8.0
X-AspNet-Version    4.0.30319
X-AspNetMvc-Version 4.0
X-Powered-By    ASP.NET
X-SourceFiles   =?UTF-8?B?XFxwc2ZcaG9tZVxkb2N1bWVudHNcdmlzdWFsIHN0dWRpbyAyMDEyXFByb2plY3RzXE12YzRQbGF5Z3JvdW5kXE12YzRQbGF5Z3JvdW5kXEhvbWVcQ29udmVydExvZ0luZm9Ub1htbA==?=

応答本文:

{"prop":1,"myArray":[1,"two",3]}
24
Jaime Torres

VB.NETバージョン

わかりましたので、MVC 4 WEB APIに複数のパラメーターをポストするための実行可能なメソッドを探すために数時間費やしましたが、私が見つけたのは 'GET'アクションまたはちょうど平らに機能しませんでした。しかし、ようやくこれが機能するようになり、自分のソリューションを共有すると思いました。

  1. NuGetパッケージを使用して、_JSON-js json2_および_Json.NET_をダウンロードします。 NuGetパッケージをインストールする手順:

    (1)Visual Studioで、Website>NuGetパッケージの管理...に移動します enter image description here

    (2)検索バーにjson(またはその目的の何か)を入力し、_JSON-js json2_および_Json.NET_を見つけます。それらをダブルクリックすると、パッケージが現在のプロジェクトにインストールされます。enter image description here

    (3)NuGetはプロジェクトディレクトリの_~/Scripts/json2.min.js_にjsonファイルを自動的に配置します。 json2.min.jsファイルを見つけて、Webサイトのヘッドにドラッグアンドドロップします。 :.js(javascript)ファイルのインストール手順については、このソリューションをお読みください。

  2. 目的のパラメーターを含むクラスオブジェクトを作成します。これを使用して、APIコントローラーのパラメーターにアクセスします。サンプルコード:

    _Public Class PostMessageObj
    
    Private _body As String
    Public Property body As String
        Get
            Return _body
        End Get
        Set(value As String)
            _body = value
        End Set
    End Property
    
    
    Private _id As String
    Public Property id As String
        Get
            Return _id
        End Get
        Set(value As String)
            _id = value
        End Set
    End Property
    End Class
    _
  3. 次に、POSTアクションに使用する実際のMVC 4 Web APIコントローラーをセットアップします。その中で、Json.NETを使用して、ポストされた文字列オブジェクトをデシリアライズします。適切な名前空間を使用します前の例を続けて、ここに私のコードがあります:

    _Public Sub PostMessage(<FromBody()> ByVal newmessage As String)
    
    Dim t As PostMessageObj = Newtonsoft.Json.JsonConvert.DeserializeObject(Of PostMessageObj)(newmessage)
    
    Dim body As String = t.body
    Dim i As String = t.id
    
    End Sub
    _
  4. 文字列化されたJSONオブジェクトを受け取るようにAPIコントローラーを設定したので、$。ajaxを使用してクライアント側からPOSTアクションを自由に呼び出すことができます;前の例を続けて、ここにあります私のコード(localhost + rootpathを適切に置き換えてください):

    _var url = 'http://<localhost+rootpath>/api/Offers/PostMessage';
    var dataType = 'json'
    var data = 'nothn'
    var tempdata = { body: 'this is a new message...Ip sum lorem.',
        id: '1234'
    }
    var jsondata = JSON.stringify(tempdata)
    $.ajax({
        type: "POST",
        url: url,
        data: { '': jsondata},
        success: success(data),
        dataType: 'text'
    });
    _

ご覧のとおり、基本的にJSONオブジェクトを作成し、それを文字列に変換し、単一のパラメーターとして渡し、JSON.NETフレームワークを介して再構築しています。 APIコントローラーに戻り値を含めなかったため、success()関数に任意の文字列値を配置しました。


著者のメモ

これは、ASP.NET 4.0、WebForms、VB.NET、およびMVC 4 Web API Controllerを使用してVisual Studio 2010で行われました。 MVC 4 Web APIとVS2010の統合に問題がある場合は、パッチをダウンロードして可能にしてください。 Microsoftのダウンロードセンターからダウンロードできます。

(主にC#で)役立ついくつかの追加の参照を以下に示します。

2
Lopsided

この投稿を参照すると、答えが見つかると思います: JSONをC#動的オブジェクトに逆シリアル化しますか?

ここで必要なことを達成するにはさまざまな方法があります。 System.Web.Helpers.Jsonのアプローチ(いくつかの答えがあります)が最も簡単なようです。

2
Acorn

// asp.net mvcのシンプルなjsonオブジェクト

var model = {"Id": "xx", "Name":"Ravi"};
$.ajax({    url: 'test/[ControllerName]',
                        type: "POST",
                        data: model,
                        success: function (res) {
                            if (res != null) {
                                alert("done.");
                            }
                        },
                        error: function (res) {

                        }
                    });


//model in c#
public class MyModel
{
 public string Id {get; set;}
 public string Name {get; set;}
}

//controller in asp.net mvc


public ActionResult test(MyModel model)
{
 //now data in your model 
}
1
Ravi Anand

私のクライアント側(cshtmlファイル)は、DataTablesを使用してグリッドを表示していました(素晴らしいInfragisticsコントロールを使用しています)。そして、ユーザーが行をクリックすると、行イベントとそのレコードに関連付けられた日付をキャプチャして、サーバーに戻り、取引などの追加のサーバー側リクエストを行います。そして、いいえ-I DID文字列化しない...

DataTables defはこれとして開始し(多くのものを除外)、クリックイベントは以下のようになり、Jsonオブジェクトにプッシュします:

    oTablePf = $('#pftable').dataTable({         // INIT CODE
             "aaData": PfJsonData,
             'aoColumnDefs': [                     
                { "sTitle": "Pf Id", "aTargets": [0] },
                { "sClass": "**td_nodedate**", "aTargets": [3] }
              ]
              });

   $("#pftable").delegate("tbody tr", "click", function (event) {   // ROW CLICK EVT!! 

        var rownum = $(this).index(); 
        var thisPfId = $(this).find('.td_pfid').text();  // Find Port Id and Node Date
        var thisDate = $(this).find('.td_nodedate').text();

         //INIT JSON DATA
        var nodeDatesJson = {
            "nodedatelist":[]
        };

         // omitting some code here...
         var dateArry = thisDate.split("/");
         var nodeDate = dateArry[2] + "-" + dateArry[0] + "-" + dateArry[1];

         nodeDatesJson.nodedatelist.Push({ nodedate: nodeDate });

           getTradeContribs(thisPfId, nodeDatesJson);     // GET TRADE CONTRIBUTIONS 
    });
0
bob.mazzo

数か月前に、Json形式の日付をコントローラーに送り返す必要があるという奇妙な状況に遭遇しました。髪を抜いた後に思いついたのは次のとおりです。

私のクラスは次のようになります。

public class NodeDate
{
    public string nodedate { get; set; }
}
public class NodeList1
{
    public List<NodeDate> nodedatelist { get; set; }
}

と私のC#コードは次のとおりです:

        public string getTradeContribs(string Id, string nodedates)
    {            
        //nodedates = @"{""nodedatelist"":[{""nodedate"":""01/21/2012""},{""nodedate"":""01/22/2012""}]}";  // sample Json format
        System.Web.Script.Serialization.JavaScriptSerializer ser = new System.Web.Script.Serialization.JavaScriptSerializer();
        NodeList1 nodes = (NodeList1)ser.Deserialize(nodedates, typeof(NodeList1));
        string thisDate = "";
        foreach (var date in nodes.nodedatelist)
        {  // iterate through if needed...
            thisDate = date.nodedate;
        }   
    }

そのため、「nodes」オブジェクトのnodedates Jsonオブジェクトパラメータをデシリアライズできました。もちろん、クラス "NodeList1"を使用して機能させます。

これがお役に立てば幸いです...ボブ

0
bob.mazzo