6

我在 WCF 中编写了几个类(数据合同和服务合同),我正在尝试在 JSON 中序列化和反序列化。如果我需要以下 JSON 结构,我将如何创建 DataContract(s):

{
  "response": {
    "locations": {
      "location": [
        {
          "id": "12",
          "name": "Hello",
          "statusid": "78"
        },
        {
          "id": "5",
          "name": "Ann",
          "statusid": "8"
        }
      ]
    },
    "error": "404 error"
  }
}

上面的结构非常简单,在位置下可以有多个位置细节,如上所述。所以我需要得到一个数组/列表到“位置”数据成员,如下所述。目前我只有以下 DataContract:

[DataContract]
    public class Response
    {
        [DataMember]
        public string locations { get; set; }

        [DataMember]
        public string error{ get; set; }
    }

请让我知道如何解决这个问题?

4

3 回答 3

12

您要查找的完整对象应构造为:

[DataContract(Name="response")]
public class Response
{
    [DataMember(Name = "locations")]
    public IEnumerable<Location> Locations { get; set; }

    [DataMember(Name = "error")]
    public string Error { get; set; }
}

[DataContract(Name = "location")]
public class Location
{
    [DataMember(Name = "id")]
    public string Id { get; set; }

    [DataMember(Name = "name")]
    public string Name { get; set; }

    [DataMember(Name = "statusid")]
    public string StatusId { get; set; }
}

您需要设置对象层次结构,如 和 所示{}以及 IEnumerable / 数组属性,如所需 JSON 输出中的[和所示。]

该站点可能会造成混淆,因为没有简单的示例,但请查看介绍 JSON以获得对语法的基本了解。我遇到的另一个很好的站点是ASP.NET Web API 中的 JSON 和 XML 序列化,仅提供了一些简单的示例。

感谢 vittore 的一些指导,我注意到要构建与 JSON 输出完全匹配的对象,您将需要以下对象:

[DataContract]
public class ResponseParent
{
    [DataMember(Name = "response")]
    public Response ResponseInstance { get; set; }
}

[DataContract]
public class Response
{
    [DataMember(Name = "locations")]
    public LocationCollectionIntermediate Locations { get; set; }

    [DataMember(Name = "error")]
    public string Error { get; set; }
}

[DataContract]
public class LocationCollectionIntermediate
{
    [DataMember(Name = "location")]
    public IEnumerable<Location> Locations { get; set; }
}

[DataContract]
public class Location
{
    [DataMember(Name = "id")]
    public string Id { get; set; }

    [DataMember(Name = "name")]
    public string Name { get; set; }

    [DataMember(Name = "statusid")]
    public string StatusId { get; set; }
}

我在这里将这些添加到第二个代码块中,因为这样的结构看起来不必要地复杂。但是,如果您处于可以更改 JSON 的预期输出的位置,我将使用第一个块,另外更改将两Id列转换为int类型。

创建这些类型是为了支持类似于在WCF Service 中设置以返回 JSON的服务,并使用以下代码进行测试:

string json;
using (var ms = new MemoryStream())
{
    var ser = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(ResponseParent));
    ser.WriteObject(ms, r);
    json = System.Text.Encoding.UTF8.GetString(ms.GetBuffer(), 0, Convert.ToInt32(ms.Length)); 
}

DataContractJsonSerializer的详细信息

另请注意,如果您可以选择设置 RESTful Web 服务,则可以遵循如何在 60 秒内创建 JSON WCF RESTful 服务的指南。

于 2013-03-13T19:33:34.953 回答
3

一旦有了准确的属性结构,您还可以使用JavaScriptSerializerSystem.Web.Script.Serialization(自 .NET 3.5 起)

像这样的东西会起作用:

string jsonString;

JavaScriptSerializer serializer = new JavaScriptSerializer();
Response responseObject = serializer.Deserialize<Response>(jsonString);

甚至比 using 更简单DataContractSerializer,尽管我不完全确定它的注意事项。我已经多次使用它,没有任何问题。

您还可以添加自定义JavaScriptConverter ,这样可以相对轻松地实现更好的动态 JSON 解析方式。

这样动态解析也很简单:

string jsonString;

JavaScriptSerializer serializer = new JavaScriptSerializer();
dynamic responseObject = serializer.Deserialize<object>(jsonString);

responseObject["locations"] = ...
于 2015-04-27T10:41:26.300 回答
3

访问http://json.codeplex.com/。利用

JsonConvert.SerializeObject()

将您的对象转换为 JSON 字符串。利用

JsonConvert.PopulateObject

将 JSON 字符串转换为对象。

于 2013-03-13T19:00:47.027 回答