65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 WCF 在 .NET 中消费 JSON 数据

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.74/5 (11投票s)

2009年2月4日

CPOL

2分钟阅读

viewsIcon

106221

downloadIcon

2385

代码演示如何在 .NET 应用程序中使用 .NET 3.5 SP1 中的新的 JSON 数据契约支持来消费 JSON 数据。

解析 .NET 代码中的任意 JSON

一种新兴的流行格式,用于在线共享内容的是 JSON,JavaScript 对象表示法的缩写。它旨在比 XML 稍微高效一些,并在许多基于 AJAX 的 Web 应用程序中找到了用武之地。有些公司实际上要求您使用 JSON 与他们的 API 进行交互,因此以强类型的方式解析和发出任意 JSON 是一种有价值的工具。从 .NET 3.5 SP1 开始,我们配备了 DataContractJsonSerializer

本教程将向您展示如何获取任意 JSON 片段并将其转换为对象。让我们从流行的 Flikr 图片共享网站获取一个 feed。获取 最新的公共照片 feed,您可能会得到如下 JSON:

jsonFlickrFeed({
    "title": "Uploads from everyone",
    "link": "http://www.flickr.com/photos/",
    "description": "",
    "modified": "2009-02-04T07:24:51Z",
    "generator": "http://www.flickr.com/",
    "items": [
            {
            "title": "Ohayo2009-224",
            "link": "http://www.flickr.com/photos/14427733@N07/3252849052/",
            "media": {
                "m":"http://farm4.static.flickr.com/3534/3252849052_ab77f0e3af_m.jpg"
            },            
            "date_taken": "2009-01-29T16:47:42-08:00",            
            "description": "Description of photo appears here",
            "published": "2009-02-04T07:24:51Z",
            "author": "Author of photos appears here",
            "author_id": "14420000@N00",
            "tags": "2009 ohayo"
        },
        .. more items
    ]
})

将数据分解为对象

现在,诀窍是尝试将数据结构映射到一组 .NET 对象,并使用 DataMember 属性将我们对象的每个属性映射到 feed 中的一个字段。类本身将使用 DataContract 属性进行注释。让我们看看我们如何为我们正在使用的 Flikr feed 中的“item” 执行此操作

[DataContract()]
public class FlikrItem : IExtensibleDataObject 
{
    [DataMember(Name="title")]
    public String Title { get; set; }

    [DataMember(Name = "link", IsRequired = true)]
    public String Link { get; set; }

    [DataMember(Name="media")]
    public FlikrMedia Media { get; set; }

    // WCF stores any items we did not map here
    public ExtensionDataObject ExtensionData { get; set; }
}

如您所见,我们使用 DataMember 属性将 JSON 对象中的元素连接到我们的 .NET 属性。我们还实现了 IExtensibleDataObject 接口,并告诉 WCF 忽略我们尚未显式映射的任何元素,并将它们放入实际上是一个 bucket 中。请注意,media 属性映射到 FlikrMedia 的一个实例,这是我们必须声明的另一个类型,用于存储实际的媒体图像。总而言之,我们的对象模型将类似于:

CodeProject-ArbJson-Code

读取 JSON

接下来,我们必须使用 DataContractJsonSerializer 将 JSON 数据读取到我们的对象中。在执行此操作之前,我们必须手动处理字符串以删除围绕实际 JSON 数据的回调包装,因为 jsonFlikrFeed() 包装否则会导致解析失败。接下来,我们必须将从 API 下载的字符串转换为字节缓冲区,将其放入内存流中,然后将其传递给序列化程序。

static FlikrFeed ParseFeed(String inputContent)
{
    // Remove the jsonFlikrFeed() callback cladding.
    inputContent = inputContent.Trim();
    if (inputContent.StartsWith("jsonFlickrFeed("))
        inputContent = inputContent.Remove(0, "jsonFlickrFeed(".Length);
    if (inputContent.EndsWith(")"))
        inputContent = inputContent.Substring(0, inputContent.Length-1);

    // Create a serializer for our type
    DataContractJsonSerializer serializer = 
       new DataContractJsonSerializer(typeof(FlikrFeed));

    // Convert the text to a buffer of bytes
    using (MemoryStream stream = 
           new MemoryStream(Encoding.Unicode.GetBytes(inputContent)))
    {
        // Convert the stream buffer to an object with our serializer.
        return serializer.ReadObject(stream) as FlikrFeed;
    }
}

就这样!现在我们得到了一个 FlikrFeed 实例,我们可以浏览 Items 集合,并深入到媒体项目预览图像中。您可以将这些原则应用于您希望交互的任何 JSON feed!

CodeProject-ArbJson-Result.png

注释

  • 有关 JSON 的更常规信息,Google 的 GWT FAQ 提供了对 JSON 基本知识的相当不错的介绍,网址为 Google 的 GWT FAQ。这介绍了将 JSON 包装在回调函数中的想法(如我们的示例中的 flikr 所做的那样)。
  • 您需要安装 .NET Framework 3.5 SP1 才能运行此代码,并且可以在 System.ServiceModel.Web 命名空间中找到序列化程序。
© . All rights reserved.