将 JSON 对象反序列化为 List<type> 不适用于 asmx 服务

Posted

技术标签:

【中文标题】将 JSON 对象反序列化为 List<type> 不适用于 asmx 服务【英文标题】:Deserializing JSON objects as List<type> not working with asmx service 【发布时间】:2010-09-29 00:21:27 【问题描述】:

我在反序列化我的 JSON 字符串时遇到问题。我有一个 person 类型的类,它具有 int 类型的序列号、名字和姓氏的公共属性。我想以 JSON 格式传递这些对象的数组并将它们反序列化为列表,以便我可以在服务器上循环它们,但 ASP.NET 表示不支持将它们反序列化为数组。我已经验证了我正在生成的 JSON,它是有效的。 ASP.NET 在反序列化之前需要拥有的 JSON 有什么特别之处吗?有趣的是,如果我将 list 对象序列化为 JSON,它看起来与我正在生成的 JSON 完全一样。我一定遗漏了一些东西......为了澄清,我正在使用 ASP.NET Ajax 库进行反序列化。这是我从网络服务中得到的:

"Message":"Type \u0027System.Collections.Generic.IDictionary`2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Object, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]\u0027 不支持数组的反序列化。"

实际上不幸的是,这似乎与反序列化没有任何关系,您似乎无法将 JSON 对象数组传递给 asmx Web 服务。我对么?如果您不能这样做,是否可以将 JSON 对象的集合传递给 Web 服务并使用 ASP.NET 和 C# 在服务器上处理它们?

更新:

好的,这是我的代码。这是人员类:

public class person

    public person()
    
        //
        // TODO: Add constructor logic here
        //
    

    public int seq
    
        get;
        set;
     

    public string firstName
    
        get;
        set;
     
     public string lastName
     
        get;
        set;
     

  

这是我的 JSON 字符串:

["seq":1,"firstName":"Chris","lastName":"West***",
"seq":2,"firstName":"sayyl","lastName":"west***"]  

这是我正在使用的代码

    [WebMethod]
    public void updatePeople(string json)
    
        IList<person> people = 
         new javascriptSerializer().Deserialize<IList<person>>(json);

        //do stuff...
    

【问题讨论】:

你用什么来序列化/反序列化 json?抛出的确切异常是什么? 对不起,我正在使用 asp.net ajax 库来反序列化。我正在根据表单输入手动将对象序列化为 json,当使用链接到 json.org 的 json 验证器进行测试时,它说它是有效的。 【参考方案1】:

我想通了。我没有将我的 JSON 包装在像 ASP.NET Ajax 需要的对象中。对于此问题的未来查看者,所有 JSON 对象在发送到 Web 服务之前必须用主对象包装。最简单的方法是在 JavaScript 中创建对象并使用 json2.js 之类的东西对其进行字符串化。此外,如果使用 asmx Web 服务,对象必须具有 __type 属性才能正确序列化。这方面的一个例子可能是:

var person=new object;
person.firstName="chris";
person.lastName="West***";
person.seq=-1;
var data=new object;
data.p=person;
JSON.stringify(data);

这将创建一个名为p 的对象,该对象将包装一个人对象。然后可以将其链接到 Web 服务中的参数pperson 类型的列表的制作方式类似,接受使用人员数组而不是单个对象。我希望这对某人有所帮助。

【讨论】:

这是我类似问题的确切解决方案。谢谢! 对于 Persons 数组,我需要一个 p 变量来包装每个 Person ,还是需要一个 p 来将整个数组包装在 JSON 字符串中? @dan_l 这取决于您的网络服务期望什么。如果您的 web 服务期待 List&lt;Person&gt; people,您应该执行 data.people = getPersonList() 或其他操作。如果您的网络服务需要Person fred,您应该选择data.fred = getFred()。我 98% 确定参数名称应该匹配。【参考方案2】:

您能否展示您尝试反序列化的 JSON 字符串以及您使用 Deserialize 方法的方式?以下工作正常:

using System;
using System.Collections.Generic;
using System.Web.Script.Serialization;

namespace Test

    class Program
    
        class Person 
        
            public int SequenceNumber  get; set; 
            public string FirstName  get; set; 
            public string LastName  get; set; 
        

        public static void Main() 
        
            string json = "[\"SequenceNumber\":1,\"FirstName\":\"FN1\",\"LastName\":\"LN1\",\"SequenceNumber\":2,\"FirstName\":\"FN2\",\"LastName\":\"LN2\"]";
            IList<Person> persons = new JavaScriptSerializer()
                .Deserialize<IList<Person>>(json);
            Console.WriteLine(persons.Count);
        
    

【讨论】:

【参考方案3】:

或者更简单,当你在使用 $.ajax(...) 时

data:"\"key\":"+JSON.stringify(json_array)+"",

然后在代码的另一边,让你的函数使用参数“object key”

[WebMethod]
public static return_type myfunction(object key)...

【讨论】:

【参考方案4】:

服务器端

[WebMethod]
public void updatePeople(object json)

客户端

var person = "["seq":1,"firstName":"Chris","lastName":"West***"
,"seq":2,"firstName":"sayyl","lastName":"west***"]";

var str = "'json':'" + JSON.stringify(person) + "'";

【讨论】:

【参考方案5】:

我认为问题在于您必须反序列化什么类型。您正在尝试反序列化类型

列表

但你应该尝试只反序列化

列表

由于接口无法实例化,这可能是根本问题。

【讨论】:

以上是关于将 JSON 对象反序列化为 List<type> 不适用于 asmx 服务的主要内容,如果未能解决你的问题,请参考以下文章

将 JSON 反序列化为对象

将 JSON 反序列化为对象

将 JSON 数组反序列化为 List<T> C# 时出错

使用Jackson将JSON数组反序列化为单个Java对象

将 JSON 反序列化为 List<List<KeyValuePair>> 结果为空

使用 Json.NET 将异构 JSON 数组反序列化为协变 List<>