【问题标题】:Deserializing JSON from ASP.net web service into C# object将 ASP.net Web 服务中的 JSON 反序列化为 C# 对象
【发布时间】:2012-05-03 15:13:29
【问题描述】:

在这里阅读了一天的帖子后,我仍然无法让它工作,所以希望这对这里的人有意义。

网络服务返回这个简单的 JSON

{"d":{"__type":"TestWebServices.Person","Name":"Bob","FavoriteColor":"Green","ID":0}}

那我用C#代码反序列化

DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(Person));
Person someone = (Person)jsonSerializer.ReadObject(responseStream);

当我使用这个模型时,有人被创建但所有属性都是空的

[DataContract]
public class Person {
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public string FavoriteColor { get; set; }
    [DataMember]
    public int ID { get; set; }
}

我尝试更直接地使用这个模型

[DataContract]
public class Person {
    [DataMember]
    public PersonItem d { get; set; }
}
[DataContract]
public class PersonItem {
    [DataMember]
    public string __Type { get; set; }
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public string FavoriteColor { get; set; }
    [DataMember]
    public int ID { get; set; }
}

得到了这个错误,我什至不知道从哪里开始

元素“:d”包含映射到名称“:GEMiniWebServices.Person”的类型的数据。反序列化器不知道映射到此名称的任何类型。考虑使用 DataContractResolver 或将与“TestWebServices.Person”对应的类型添加到已知类型列表中 - 例如,通过使用 KnownTypeAttribute 属性或将其添加到传递给 DataContractSerializer 的已知类型列表中。

有什么想法吗? 谢谢

【问题讨论】:

  • 如果添加Service Reference,生成的客户端会为你反序列化响应。

标签: c# asp.net json


【解决方案1】:

__Type 永远不应该是你的对象的一部分。这是对序列化程序的提示。此外,您在 JSON 对象中的类型提示很糟糕。 Stand-Alone JSON Serialization 说:

为了保留类型标识,在将复杂类型序列化为 JSON 时, 可以添加“类型提示”,反序列化器识别提示并 采取适当的行动。 “类型提示”是一个 JSON 键/值对,带有 “__type”的键名(两个下划线后跟单词“type”)。 该值是一个 JSON 字符串,格式为 “DataContractName:DataContractNamespace”(直到第一个 冒号是名称)。

类型提示与定义的 xsi:type 属性非常相似 XML Schema Instance 标准并在序列化/反序列化时使用 XML。

由于潜在的冲突,名为“__type”的数据成员被禁止 带有类型提示。

如果您将 __type 声明重写为 Person:#TestWebServices 或删除它,它适用于以下情况:

namespace TestWebServices
{
    [KnownType(typeof(Person))]
    [DataContract]
    public class PersonWrapper
    {
        [DataMember]
        public Person d { get; set; }
    }
    [DataContract]
    public class Person
    {
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public string FavoriteColor { get; set; }
        [DataMember]
        public int ID { get; set; }
    }
}

【讨论】:

  • 感谢 JamieSee 提供的信息。我也试过没有“__type”并得到同样的错误。 Web 服务正在创建该类型提示,但不确定我能做些什么。
  • 添加评论 - 如果我从 JSON 中去掉 "d":{"__type":"GEMiniWebServices.Person" DataContractJsonSerializer 和 JavaScriptSerializer 都可以将数据解析为 PersonItem 对象所以是"d":{"__type":" 的目的是什么?这显然是在把一些简单的事情变得复杂。想法?
  • 这里描述了这个问题codeproject.com/Articles/72443/…文章建议剥离导致问题的json。
  • 如果你将__type 声明重写为Person:#TestWebServices 或删除它,它就可以工作。
  • 这里是与“d”的“目的”相关的a question:{.
【解决方案2】:

尝试添加(我在这里有点刺痛,所以确切的命名空间可能不正确)

[DataContract(Namespace = "http://schemas.datacontract.org/2004/07/TestWebServices.Person")]

到 Person 上的 DataContractAttribute。

[DataContract(Namespace = "http://schemas.datacontract.org/2004/07/TestWebServices.Person")]
public class Person {
    [DataMember]
    public PersonItem d { get; set; }
}
[DataContract]
public class PersonItem {
    [DataMember]
    public string __Type { get; set; }
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public string FavoriteColor { get; set; }
    [DataMember]
    public int ID { get; set; }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多