複雑な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データを渡すにはどうすればよいですか?
ありがとう、ノートル
問題は、dataType
とdata
パラメーターの形式です。これをサンドボックスでテストしたところ、次のように動作します。
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]}
わかりましたので、MVC 4 WEB APIに複数のパラメーターをポストするための実行可能なメソッドを探すために数時間費やしましたが、私が見つけたのは 'GET'アクションまたはちょうど平らに機能しませんでした。しかし、ようやくこれが機能するようになり、自分のソリューションを共有すると思いました。
NuGetパッケージを使用して、_JSON-js json2
_および_Json.NET
_をダウンロードします。 NuGetパッケージをインストールする手順:
(1)Visual Studioで、Website>NuGetパッケージの管理...に移動します
(2)検索バーにjson(またはその目的の何か)を入力し、_JSON-js json2
_および_Json.NET
_を見つけます。それらをダブルクリックすると、パッケージが現在のプロジェクトにインストールされます。
(3)NuGetはプロジェクトディレクトリの_~/Scripts/json2.min.js
_にjsonファイルを自動的に配置します。 json2.min.jsファイルを見つけて、Webサイトのヘッドにドラッグアンドドロップします。 注:.js(javascript)ファイルのインストール手順については、このソリューションをお読みください。
目的のパラメーターを含むクラスオブジェクトを作成します。これを使用して、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
_
次に、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
_
文字列化された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#で)役立ついくつかの追加の参照を以下に示します。
この投稿を参照すると、答えが見つかると思います: JSONをC#動的オブジェクトに逆シリアル化しますか?
ここで必要なことを達成するにはさまざまな方法があります。 System.Web.Helpers.Jsonのアプローチ(いくつかの答えがあります)が最も簡単なようです。
// 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
}
私のクライアント側(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
});
数か月前に、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"を使用して機能させます。
これがお役に立てば幸いです...ボブ