如何从嵌套结构中检索值

时间:2014-06-02 01:59:37

标签: c# asp.net facebook struct

我正在创建应用程序以使用FQL从我的Facebook页面检索数据。 fql查询是:

select id, text, attachment.media.image.src FROM comment 
where post_id IN (SELECT post_id from stream where 
                  source_id = "mypageid" AND  actor_id = "mypageid" LIMIT 100)

我通过这种方式获得了ID和TEXT的值:

public class MyComments
{
    public string id { get; set; } // this is comment id
    public string text { get; set; } // this is the comment
}

List<MyComments> q = JsonConvert.DeserializeObject<List<MyComments>>
                                                     (results.data.ToString());
if (q.Count != 0)
{
    post_id = q[0].id.ToString();
    post_text = q[0].text.ToString();
}

但是如何获得SRC的值,因为它是结构附件中的结构&gt;在struct media中&gt;在struct image&gt; string src。

是否有可能获得字符串SRC的值?在c#代码?

拜托,伙计们,先谢谢。

1 个答案:

答案 0 :(得分:1)

我还没玩过FQL,但是JSON很容易处理。

要做的第一件事是检查FQL返回的JSON对象,看它是否有嵌套的结构对象。假设确实如此,则需要为每个嵌套对象创建一个类。

假设您有类似于此的JSON结构:

[{
    "id": "<comment id>",
    "text": "<comment text>",
    "attachment": {
        "media": {
            "image": {
                src: "<image source string>"
            }
        }
    }
}, {
    ...
}]

为了将其解压缩到C#类,您需要为每个级别提供一个类:attachment - &gt;媒体 - &gt;图像:

public class MyComments
{
    public string id { get; set; }
    public string text { get; set; }
    public Attachment attachment { get; set; }

    public class Attachment
    {
        public Media media { get; set; }
    }

    public class Media 
    {
        public Image image { get; set; }
    }

    public class Image 
    {
        public string src { get; set; }
    }
}

当然,如果您在单个响应之外使用这些类,则可以取消嵌套它们并添加您可能使用的任何其他字段。我发现使用这种方式更简单,因为所有内容都封装在结果记录类中。

在您对FQL的响应进行反序列化后,您应该能够访问src项目(在上面的代码中):

post_src = q[0].attachment.media.image.src;

请注意JSON与您为其构建的结构相匹配,否则您将获得一些反序列化错误。特别注意阵列 - 除非你为它们做好准备,否则它们会让你感到困惑。


编辑:[删除了数组中的部分,因为它不适合您的实际用例]


这是一组将反序列化您在PasteBin上发布的JSON的类:

public class MyComments
{
    public string post_id;
    public string message;
    public Attachment attachment;


    public class Attachment
    {
        public Media[] media;
    }

    public class Media
    {
        public string href;
        public string alt;
        public string type;
        public string src;
        public Photo photo;
    }

    public class Photo
    {
        public string aid;
        public string pid;
        public string fbid;
        public string owner;
        public int index;
        public int width;
        public int height;
        public Image[] images;
    }

    public class Image
    {
        public string src;
        public int width;
        public int height;
    }
}

针对发布的JSON进行测试:

MyComments comment = JsonConvert.DeserializeObject<MyComments>(jsrc);
Console.WriteLine("Source: {0}", comment.attachment.media[0].photo.images[0].src);

输出:

Source: https://fbcdn-sphotos-a-a.akamaihd.net/hphotos-ak-xfa1/t1.0-9/s720x720/10288743_852243528123890_8104585654908358176_n.jpg

请注意,数组可以为空,因此上述内容可能会因IndexOutOfRangeException而失败。在索引之前,请始终测试数组的Length

我在MyComments.Photo类中编写了一些代码,以查找符合条件的图像 - 例如,最大尺寸。像这样:

public Image LargestImage()
{
    return images.OrderByDescending(i => i.width).ThenByDescending(i => i.height).FirstOrDefault();
}

然后,您可以随时获取最大的图像,无论图像的输入顺序如何,或null如果图像列表为空:

var img = comment.attachment.media[0].photo.LargestImage();
if (img != null)
    Console.WriteLine("Source: {0}", img.src);

附加评论的所有媒体的最大图像来源列表:

var q = 
    (
        from m in comment.attachment.media
        let img = m.photo.LargestImage()
        where img != null
        select img.src
    ).ToList();

或没有LargestImage方法:

var q = 
    (
        from m in comment.attachment.media
        let img = m.photo.images
            .OrderByDescending(i => i.width)
            .ThenByDescending(i => i.height)
            .FirstOrDefault()
        where img != null
        select img.src
    ).ToList();

即使出于任何原因无法从JSON中解析出images条目,也能正常工作。