通过 jQuery 将 JSON 数据发布到 ASP .NET MVC 4 控制器操作

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17370062/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 18:55:19  来源:igfitidea点击:

Posting JSON data via jQuery to ASP .NET MVC 4 controller action

jqueryasp.net-mvcjson

提问by Notre

I'm having trouble trying to pass a complex JSON object to an MVC 4 controller action. As the JSON content is variable, I don't want MVC to map individual properties/elements of the JSON to parameters in the action method's parameter list. I just want to get the data as a single JSON string parameter in the controller action.

我在尝试将复杂的 JSON 对象传递给 MVC 4 控制器操作时遇到问题。由于 JSON 内容是可变的,我不希望 MVC 将 JSON 的各个属性/元素映射到操作方法的参数列表中的参数。我只想在控制器操作中将数据作为单个 JSON 字符串参数获取。

Here's the signature of my action method:

这是我的操作方法的签名:

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

And here's my attempt to post some JSON data, from my browser:

这是我尝试从浏览器发布一些 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
    });

When I hit my breakpoint at the beginning of the ConvertLogInfoToXML method, jsonOfLog is null.

当我在 ConvertLogInfoToXML 方法的开头遇到断点时,jsonOfLog 为空。

If I change what 'json' variable is set to in the JavaScript to have the jsonOfLog property be a simple string, e.g. :

如果我更改在 JavaScript 中设置的 'json' 变量,让 jsonOfLog 属性成为一个简单的字符串,例如:

json = { jsonOfLog: "simple string" };

then when my breakpoint at the beginning of the ConvertLogInfoToXML method is hit, jsonOfLog is the value of the string (e.g. "simple string").

然后当我在 ConvertLogInfoToXML 方法开头的断点被命中时,jsonOfLog 是字符串的值(例如“简单字符串”)。

I tried changing the type of the jsonOfLog parameter in the action method to be of type object:

我尝试将 action 方法中 jsonOfLog 参数的类型更改为 object 类型:

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

Now, with the original JavaScript code (where I'm passing a more complex 'data' object), jsonOfLog gets the value of {object}. But the debugger doesn't show any more details in a watch window, and I don't know what methods I can use to operate on this variable.

现在,使用原始 JavaScript 代码(我在其中传递更复杂的“数据”对象),jsonOfLog 获取 {object} 的值。但是调试器没有在观察窗口中显示更多细节,我不知道我可以使用什么方法来操作这个变量。

How do I pass JSON data to a MVC controller, where the data passed is a stringified complex object?

如何将 JSON 数据传递给 MVC 控制器,其中传递的数据是字符串化的复杂对象?

Thanks, Notre

谢谢,诺特

采纳答案by Jaime Torres

The problem is your dataTypeand the format of your dataparameter. I just tested this in a sandbox and the following works:

问题在于您dataType和您的data参数格式。我刚刚在沙箱中对此进行了测试,结果如下:

C#

C#

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

javascript

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>

Pay special attention to data, when sending text, you need to send a variable that matches the name of your parameter. It's not pretty, but it will get you your coveted unformatted string.

特别注意data,发送文本时,您需要发送一个与您的参数名称匹配的变量。它不是很漂亮,但它会让你得到你梦寐以求的无格式字符串。

When running this, jsonOfLog looks like this in the server function:

运行它时,jsonOfLog 在服务器函数中看起来像这样:

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

The HTTP POST header:

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

The HTTP POST body:

HTTP POST 正文:

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

The response header:

响应头:

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==?=

The response body:

响应体:

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

回答by Lopsided

VB.NET VERSION

VB.NET 版本

Okay, so I have just spent several hours looking for a viable method for posting multiple parametersto an MVC 4 WEB API, but most of what I found was either for a 'GET' action or just flat out did not work. However, I finally got this working and I thought I'd share my solution.

好的,所以我刚刚花了几个小时寻找一种可行的方法来将多个参数发布到 MVC 4 WEB API,但我发现的大部分内容要么是针对“GET”操作,要么就是完全无效。然而,我终于得到了这个工作,我想我会分享我的解决方案。

  1. Use NuGet packages to download JSON-js json2and Json.NET. Steps to install NuGet packages:

    (1) In Visual Studio, go to Website> Manage NuGet Packages...enter image description here

    (2) Type json (or something to that effect) into the search bar and find JSON-js json2and Json.NET. Double-clicking them will install the packages into the current project.enter image description here

    (3) NuGet will automatically place the json file in ~/Scripts/json2.min.jsin your project directory. Find the json2.min.js file and drag/drop it into the head of your website. Note: for instructions on installing .js (javascript) files, read this solution.

  2. Create a class object containing the desired parameters. You will use this to access the parameters in the API controller. Example code:

    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. Then we setup the actual MVC 4 Web API controller that we will be using for the POST action. In it, we will use Json.NET to deserialize the string object when it is posted. Remember to use the appropriate namespaces. Continuing with the previous example, here is my code:

    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. Now that we have our API controller set up to receive our stringified JSON object, we can call the POST action freely from the client-side using $.ajax; Continuing with the previous example, here is my code (replace localhost+rootpath appropriately):

    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'
    });
    
  1. 使用 NuGet 包下载JSON-js json2Json.NET. 安装 NuGet 包的步骤:

    (1) 在 Visual Studio 中,转到网站>管理 NuGet 包...在此处输入图片说明

    (2) 在搜索栏中输入 json (或类似的东西)并找到JSON-js json2Json.NET。双击它们会将软件包安装到当前项目中。在此处输入图片说明

    (3) NuGet 会自动将 json 文件~/Scripts/json2.min.js放入你的项目目录中。找到 json2.min.js 文件并将其拖放到您网站的头部。注意:有关安装 .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. 现在我们已经设置了 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'
    });
    

As you can see we are basically building the JSON object, converting it into a string, passing it as a single parameter, and then rebuilding it via the JSON.NET framework. I did not include a return value in our API controller so I just placed an arbitrary string value in the success()function.

如您所见,我们基本上是在构建 JSON 对象,将其转换为字符串,将其作为单个参数传递,然后通过 JSON.NET 框架重建它。我没有在 API 控制器中包含返回值,所以我只是在success()函数中放置了一个任意字符串值。



Author's notes

作者的笔记

This was done in Visual Studio 2010 using ASP.NET 4.0, WebForms, VB.NET, and MVC 4 Web API Controller. For anyone having trouble integrating MVC 4 Web API with VS2010, you can download the patch to make it possible. You can download it from Microsoft's Download Center.

这是在 Visual Studio 2010 中使用 ASP.NET 4.0、WebForms、VB.NET 和 MVC 4 Web API 控制器完成的。对于在将 MVC 4 Web API 与 VS2010 集成时遇到问题的任何人,您可以下载补丁使其成为可能。您可以从 Microsoft 的下载中心下载它。

Here are some additional references which helped (mostly in C#):

以下是一些有帮助的其他参考资料(主要是在 C# 中):

回答by Acorn

I think you'll find your answer if you refer to this post: Deserialize JSON into C# dynamic object?

如果您参考这篇文章,我想您会找到答案:将JSON 反序列化为 C# 动态对象?

There are various ways of achieving what you want here. The System.Web.Helpers.Json approach (a few answers down) seems to be the simplest.

有多种方法可以在这里实现您想要的。System.Web.Helpers.Json 方法(几个答案)似乎是最简单的。

回答by Ravi Anand

//simple json object in asp.net mvc

//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 
}

回答by bob.mazzo

Well my client side (a cshtml file) was using DataTables to display a grid (now using Infragistics control which are great). And once the user clicked on the row, I captured the row event and the date associated with that record in order to go back to the server and make additional server-side requests for trades, etc. And no - I DID NOT stringify it...

好吧,我的客户端(一个 cshtml 文件)正在使用 DataTables 来显示网格(现在使用很棒的 Infragistics 控件)。一旦用户单击该行,我就捕获了与该记录相关联的行事件和日期,以便返回服务器并针对交易等进行额外的服务器端请求。没有 - 我没有对其进行字符串化。 ..

The DataTables def started as this (leaving lots of stuff out), and the click event is seen below where I PUSH onto my Json object :

数据表定义是这样开始的(留下了很多东西),点击事件如下所示,我把它推到我的 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 
    });

回答by bob.mazzo

Some months ago I ran into an odd situation where I also needed to send some Json-formatted date back to my controller. Here's what I came up with after pulling my hair out:

几个月前,我遇到了一个奇怪的情况,我还需要将一些 Json 格式的日期发送回我的控制器。这是我拔掉头发后想到的:

My class looks like this :

我的课是这样的:

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

and my c# code as follows :

和我的 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;
        }   
    }

and so I was able to Deserialize my nodedates Json object parameter in the "nodes" object; naturally of course using the class "NodeList1" to make it work.

所以我能够在“节点”对象中反序列化我的 nodedates Json 对象参数;当然,当然使用类“NodeList1”来使其工作。

I hope this helps.... Bob

我希望这会有所帮助.... 鲍勃