【问题标题】:Sending JSON object successfully to ASP.NET WebMethod, using jQuery使用 jQuery 将 JSON 对象成功发送到 ASP.NET WebMethod
【发布时间】:2010-11-11 21:06:09
【问题描述】:

我已经为此工作了 3 个小时并放弃了。 我只是想使用 jQuery 将数据发送到 ASP.NET WebMethod。 数据基本上是一堆键/值对。所以我尝试创建一个数组并将这些对添加到该数组中。

我的 WebMethod (aspx.cs) 看起来像这样(这对于我在 JavaScript 中构建的内容可能是错误的,我只是不知道):

[WebMethod]
public static string SaveRecord(List<object> items)
{
    ...
}

这是我的示例 JavaScript:

var items = new Array;

var data1 = { compId: "1", formId: "531" };
var data2 = { compId: "2", formId: "77" };
var data3 = { compId: "3", formId: "99" };
var data4 = { status: "2", statusId: "8" };
var data5 = { name: "Value", value: "myValue" };

items[0] = data1;
items[1] = data2;
items[2] = data3;
items[3] = data4;
items[4] = data5;

这是我的 jQuery AJAX 调用:

var options = {
    error: function(msg) {
        alert(msg.d);
    },
    type: "POST",
    url: "PackageList.aspx/SaveRecord",
    data: { 'items': items },
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    async: false,
    success: function(response) {
        var results = response.d;
    }
};
jQuery.ajax(options);

我得到错误:

Invalid JSON primitive: items.

所以,如果我这样做:

var DTO = { 'items': items };

并像这样设置数据参数:

data: JSON.stringify(DTO)

然后我得到这个错误:

Cannot convert object of type \u0027System.String\u0027 to type \u0027System.Collections.Generic.List`1[System.Object]\u0027

【问题讨论】:

  • 改变你的 web 方法来接受一个普通的旧 Object,然后看看这个对象到底是什么,然后在 web 方法中转换和处理它。
  • 问题是,您使用的是 webmethods,但没有使用为您自动生成的 JavaScript 代理类?
  • 感谢 Cory,我最初确实将 hte web 方法更改为接受一个普通对象,这帮助我弄清楚了会发生什么。谢谢!

标签: asp.net javascript jquery ajax json


【解决方案1】:

在您的示例中,如果您的数据参数为:

data: "{'items':" + JSON.stringify(items) + "}"

请记住,您需要将 JSON 字符串发送到 ASP.NET AJAX。如果您指定一个实际的 JSON 对象作为 jQuery 的数据参数,它会将其序列化为 &k=v?k=v 对。

您似乎已经阅读过它,但请再看看我的example of using a JavaScript DTO with jQuery, JSON.stringify, and ASP.NET AJAX。它涵盖了完成这项工作所需的一切。

注意:您永远不应该使用 JavaScriptSerializer 在“ScriptService”中手动反序列化 JSON(正如其他人所建议的那样)。它会根据您方法的指定参数类型自动为您执行此操作。如果你发现自己这样做了,那你就错了。

【讨论】:

    【解决方案2】:

    在使用 AJAX.NET 时,我总是将输入参数设置为一个普通的旧对象,然后使用 javascript 反序列化器将其转换为我想要的任何类型。至少通过这种方式,您可以调试并查看 Web 方法接收的对象类型。

    使用 jQuery 时需要将对象转换为字符串

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
            <asp:ScriptManager ID="sm" runat="server" EnablePageMethods="true">
                <Scripts>
                    <asp:ScriptReference Path="~/js/jquery.js" />
                </Scripts>
            </asp:ScriptManager>
            <div></div>
        </form>
    </body>
    </html>
    <script type="text/javascript" language="javascript">
        var items = [{ compId: "1", formId: "531" },
            { compId: "2", formId: "77" },
            { compId: "3", formId: "99" },
            { status: "2", statusId: "8" },
            { name: "Value", value: "myValue"}];
    
            //Using Ajax.Net Method
            PageMethods.SubmitItems(items,
                function(response) { var results = response.d; },
                function(msg) { alert(msg.d) },
                null);
    
            //using jQuery ajax Method
            var options = { error: function(msg) { alert(msg.d); },
                            type: "POST", url: "WebForm1.aspx/SubmitItems",
                            data: {"items":items.toString()}, // array to string fixes it *
                            contentType: "application/json; charset=utf-8",
                            dataType: "json",
                            async: false, 
                            success: function(response) { var results = response.d; } }; 
            jQuery.ajax(options);
    </script>
    

    以及背后的代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Services;
    using System.Web.Script.Serialization;
    using System.Web.Script.Services;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    namespace CustomEquip
    {
        [ScriptService]
        public partial class WebForm1 : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
    
            }
            [WebMethod]
            public static void SubmitItems(object items)
            {
                //break point here
                List<object> lstItems = new JavaScriptSerializer().ConvertToType<List<object>>(items);
            }
        }
    }
    

    【讨论】:

    • Kenneth,我刚刚完全按照您在上面的编码尝试了 jquery 版本,但仍然收到错误:无效的 JSON 原语:项目。 "Message":"Invalid JSON primitive: item.","StackTrace":" at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializePrimitiveObject()\r\n at ..... 该数组仍有问题,但想不通!
    • Kenneth,我试过你的 PageMethods 版本,效果很好。非常感谢。如果我无法弄清楚 jQuery 解决方案,我可能会走这条路。非常感谢。
    • 我希望对象更改只是一个调试工具...直到您让 JSON 转换正常工作。
    • 你真的不应该使用一个普通的对象,即使一开始更容易。
    【解决方案3】:

    以下是我们项目中的代码 sn-p - 我在不将对象包装为字符串和日期值时遇到了麻烦 - 希望这对某人有所帮助:

            // our JSON data has to be a STRING - need to send a JSON string to ASP.NET AJAX. 
            // if we specify an actual JSON object as jQuery's data parameter, it will serialize it as ?k=v&k=v pairs instead
            // we must also wrap the object we are sending with the name of the parameter on the server side – in this case, "invoiceLine"
            var jsonString = "{\"invoiceLine\":" + JSON.stringify(selectedInvoiceLine) + "}";
    
            // reformat the Date values so they are deserialized properly by ASP.NET JSON Deserializer            
            jsonString = jsonString.replace(/\/Date\((-?[0-9]+)\)\//g, "\\/Date($1)\\/");
    
            $.ajax({
                type: "POST",
                url: "InvoiceDetails.aspx/SaveInvoiceLineItem",
                data: jsonString,
                contentType: "application/json; charset=utf-8",
                dataType: "json"
            });
    

    服务器方法签名如下所示:

        [WebMethod]
        public static void SaveInvoiceLineItem(InvoiceLineBO invoiceLine)
        {
    

    【讨论】:

      【解决方案4】:

      用另一个属性装饰你的 [WebMethod]:

      [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
      

      我相信这是在 System.Web.Services.Scripting...

      【讨论】:

      • 我认为问题不在于服务器无法向客户端发送 JSON,问题在于服务器无法反序列化传入的 JSON。
      【解决方案5】:
      【解决方案6】:

      这是您定义数据的方式 (JSON)

      data: { 'items': items },
      

      这就是它应该的方式

      data: '{ items: " '+items +' "}',
      

      基本上你是在序列化参数。

      【讨论】:

        猜你喜欢
        • 2011-06-27
        • 2016-11-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-06
        • 2011-02-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多