将JSON反序列化为C#

3

我看到了很多JSON反序列化的简单例子,但是当涉及到稍微复杂一点的内容时,缺少样例。

我正在尝试对GetResponse的API响应进行反序列化:

简单示例:

{
    "result" : {
        "updated" : "1"
    },
    "error" : null
}

另外:

{
    "result" : null,
    "error"  : "Missing campaign"
}

这是另一个更复杂的潜在回答:
{
    "result" : {
        "CAMPAIGN_ID" : { // <-- This value will be different for each Campaign
            "name"              : "my_campaign_1",
            "from_name"         : "My From Name",
            "from_email"        : "me@emailaddress.com",
            "reply_to_email"    : "replies@emailaddress.com",
            "created_on"        : "2010-01-01 00:00:00"
        }
    },
    "error" : null
}

对于最后一个问题,我的对象应该是什么样子?

我最初想过只做像这样的东西...

 private struct GenericResult {
     public string error;
     public Dictionary<string, object> result;
 }

这将适用于我所有的响应,但是如果我没有弄错的话,要访问对象的属性,我就必须将其转换类型。

我想这样使用它:

JavaScriptSerializer jss = new JavaScriptSerializer();
var r = jss.Deserialize<GenericResult>(response_string);

// or... if I'm going to use a non-Generic object
var r = jss.Deserialize<GetCampaignResult>(response_string);

编辑

在获取数据后,实际结构存在一个问题。以下是一个实际示例:

数值

{
    "error":null,
    "result":
        {"ABQz": { // <-- As you can see, this is NOT a class name.
           "from_email" : "from@email.com",
           "created_on" : "2010-10-15 12:40:00",
           "name"       : "test_new_subscribers",
           "from_name"  : "John Smith",
           "reply_to_email": "from@email.com"
        }
    }
}

现在我不知道那个值会是什么,我陷入了困境。我想将该值包含在Campaign对象的ID中。

2个回答

1

我从你的例子中看到了三个对象。

Class CampaignId {

    String name ;
    String from_Name ;
    String from_Email ;
    \\ etc
}

Class Result {
   CampaignId campaignId  ;
}


Class RpcResponse {
   String error ;
   Result result ;
}

你需要DataMember属性吗?
这是一篇有关F# JSON序列化的好文章,我在学习时用到过: 链接 根据下面的响应进行开发,您可能想引入一些泛型:
Class CampaignId {

    String name ;
    String from_Name ;
    String from_Email ;
    \\ etc
}

Class Result<T> {
   <T> data ;
}


Class RpcResponse<T> {
   String error ;
   Result<T> result ;
}

使用以下代码初始化序列化器

JavaScriptSerializer jss = new JavaScriptSerializer(); 
var r = jss.Deserialize<RpcResponse<CampaignId>>(response_string); 

另一个不错的教程:

http://publicityson.blogspot.com/2010/06/datacontractjsonserializer-versus.html


实际上,在3.5版本之后,DCS不需要那些了。 - jcolebrand
很好了解。我正在让我的团队构建Silverlight / F# UI到一个带有JSON Rpc的Jboss服务器。但我们非常好地使用了JSON序列化,并且在泛型方面做了很多工作。许多Json RPC库都有某种信封 - 在这个例子中是结果 - 引用有效载荷... - akaphenom
如果我使用DataContractJSonSerializer,我认为我需要DataContract属性。我只是不确定我应该使用那个还是JavascriptSerializer(自3.5 SP1以来已取消弃用)。 - Armstrongest
谢谢 drachentern...我不知道那个。 - Armstrongest
我不清楚它们之间的细节差异,我们依赖DataContractJSonSerializer,但我们正在使用f#,工程师们正在编写代码(我假装管理这些天并来到这里修复我的编码)。 - akaphenom
显示剩余2条评论

1
{
    "result" : {
        "CAMPAIGN_ID" : {
            "name"              : "my_campaign_1",
            "from_name"         : "My From Name",
            "from_email"        : "me@emailaddress.com",
            "reply_to_email"    : "replies@emailaddress.com",
            "created_on"        : "2010-01-01 00:00:00"
        }
    },
    "error" : null
}

我希望它看起来像这样:[试图不使用安全网...我的编译器在哪里?!?;)]
public class TheResponse {
  public RESULT result { get; set; }
  public object error { get; set; }
}

public class RESULT {
  public CAMPAIGN_ID campaign_ID { get; set; }
}

public class CAMPAIGN_ID {
  public string name { get; set; }
  public string from_name { get; set; }
  public string from_email { get; set; }
  public string reply_to_email { get; set; }
  public string created_on { get; set; }
}

是的,你必须在某个时候、某种方式和某个地方进行强制转换。

但我认为那段代码可以在两者之间进行转换。


我没有像你那样使用嵌套对象,但我正在做类似的事情(我有一个列表,所以这样可以工作)

http://pastebin.com/7Tzr2RBz -> http://pastebin.com/NQwu3hZK(已更新)

http://pastebin.com/a0aMzcE4

这两个一起工作(一个来自客户端(JS),一个来自服务器(C#)),所以您可以看到我是如何做到的(虽然这可能没有帮助,但我尝试了)

愉快的JSON编码


JavaScriptDeserialize<TheResponse> 不会处理强制转换吗?无论如何,那是我理解的方式。 - Armstrongest
应该是的,除非您使用对象(就像我为错误所做的那样,我不确定它将是什么)。 - jcolebrand
@Atømix ~ 我甚至不使用 JSON 反序列化程序。请查看我的 pastebin。 - jcolebrand
哈哈,我刚刚意识到(在重新阅读我发布的代码时),我在两个地方重复努力了... /facepalm 确实。年轻的代码万岁!!! foreach ( WidgetPageItems w in Items ) { w.ColumnOrder = counter; counter++; }$(items).each(function() { count++; $(this).attr('columnorder', count); str.push(...); }); 但至少它展示了如何在 JSON 元素之前和之后处理它们 ;) [以及我的糟糕编码风格!] - jcolebrand

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接