我在尝试将复杂的JSON对象传递给MVC 4控制器操作时遇到了麻烦。由于JSON内容是可变的,我不希望MVC将JSON的各个属性/元素映射到action方法的参数列表中的参数。我只想将数据作为控制器操作中的单个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为空。
如果我更改JavaScript中设置的'json'变量,以使jsonOfLog属性为简单字符串,例如:
json = { jsonOfLog: "simple string" };
然后当我在ConvertLogInfoToXML方法开头的断点被命中时,jsonOfLog是字符串的值(例如“simple string”)。
我尝试将action方法中的jsonOfLog参数的类型更改为object类型:
[HttpPost]
[ValidateInput(false)]
public string ConvertLogInfoToXml(object jsonOfLog)
现在,使用原始JavaScript代码(我传递更复杂的'数据'对象),jsonOfLog获取{object}的值。但是调试器在监视窗口中没有显示任何更多细节,我不知道我可以用什么方法来操作这个变量。
如何将JSON数据传递给MVC控制器,传递的数据是一个字符串化的复杂对象?
谢谢, 巴黎
答案 0 :(得分:24)
问题在于您的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正文:
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]}
答案 1 :(得分:2)
如果您参考此帖子,我想您会找到答案:Deserialize JSON into C# dynamic object?
有多种方法可以在这里实现你想要的东西。 System.Web.Helpers.Json方法(几个答案)似乎是最简单的。
答案 2 :(得分:2)
好的,所以我花了几个小时寻找一种可行的方法将多个参数发布到MVC 4 WEB API,但我发现的大部分内容都是'GET'动作或只是平了没有用。但是,我终于有了这个工作,我想我会分享我的解决方案。
使用NuGet包下载JSON-js json2
和Json.NET
。安装NuGet包的步骤:
(1)在Visual Studio中,转到网站&gt; 管理NuGet包...
(2)在搜索栏中输入json(或其他类似内容)并找到JSON-js json2
和Json.NET
。双击它们会将软件包安装到当前项目中。
(3)NuGet会自动将json文件放在项目目录中的~/Scripts/json2.min.js
中。找到json2.min.js文件并将其拖放到您网站的头部。 注意:有关安装.js(javascript)文件的说明,请阅读 this solution 。
创建包含所需参数的类对象。您将使用它来访问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
现在我们已经设置了API控制器来接收我们的字符串化JSON对象,我们可以使用$ .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的 Download Center 下载它。
以下是一些有助于(主要是C#)的其他参考资料:
答案 3 :(得分:1)
// 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
}
答案 4 :(得分:0)
几个月前,我遇到了一个奇怪的情况,我还需要将一些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”类来使其工作。
我希望这会有所帮助.... 鲍勃
答案 5 :(得分:0)
我的客户端(cshtml文件)使用DataTables来显示网格(现在使用Infragistics控件非常棒)。 一旦用户点击该行,我就会捕获行事件和与该记录关联的日期,以便返回服务器并为交易提供额外的服务器端请求等。 不 - 我没有把它串联起来......
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
});