将具有DynamicJsonArray的复杂JSON对象反序列化为动态

时间:2015-09-15 09:25:00

标签: c# json serialization

我有一个客户端将ORDER BY发送到网络服务。

我希望webservice不知道数据的结构, 所以希望将数据反序列化为动态,然后传递给知道如何处理它的方法。

我使用SomeComplexObjectSystem.Web.Helpers.Json.Encode()方法 当SomeComplexObject包含一个集合时,我遇到了问题。 它被反序列化为DynamicJsonArray,但它在某种程度上是不可访问的 对于数据的消费者。

这些是模型类型。

Decode()

我们假设我有public class Aaa { public Bbb B { get; set; } public List<Ccc> Cccs { get; set; } } public class Bbb { public long Key { get; set; } public string Name { get; set; } public DateTime DateOfBirth { get; set; } } public class Ccc { public string Name { get; set; } public int Age { get; set; } } 类型为myAaa的对象,其属性类型为Aaa 以及42个Bbb个对象的列表。

现在:

Ccc

然后我发送它然后:

var MyAaaSerialized = System.Web.Helpers.Json.Encode(MyAaa);

最后: 这是消费者的代码。 var MyAaaDeserialized = System.Web.Helpers.Json.Decode(MyAaaSerialized); EmailemailService个类。

Postal

我可以在发送的电子邮件中看到可以访问B对象的属性。 但是,Cccs列表成员的属性不是。

当然,dynamic email = new Email(template); email.Data = MyAaaDeserialized; email.User = user; this.emailService.Send(email); 一切正常。

是否有任何简单的方法可以序列化/反序列化包含集合的复杂对象?

提前致谢,

2 个答案:

答案 0 :(得分:0)

如果我没有误解你的问题,可以通过使用如下所示使用泛型的Decode重载来解决。只需在下面的代码中指定类型(本例中为Aaa),它就可以正确打印所有ccc属性:

var myAaa = new Aaa()
{
    B = new Bbb() { Name = "someone", DateOfBirth = DateTime.Today.AddYears(-20) },
    Cccs = Enumerable.Repeat<Ccc>(new Ccc() { Age = 20, Name = "someone else" }, 42).ToList()
};

var MyAaaSerialized = System.Web.Helpers.Json.Encode(myAaa);
var MyAaaDeserialized = System.Web.Helpers.Json.Decode<Aaa>(MyAaaSerialized);
dynamic data = MyAaaDeserialized; 
foreach (Ccc newCccs in data.Cccs)
{
    Console.WriteLine($"{newCccs.Name}\t{newCccs.Age}");
}

答案 1 :(得分:0)

好的,我错了。 System.Web.Helpers.Json.Encode()Decode()正常工作。我会告诉你发生了什么:

我以前在本地使用Postal mailsender,即我过去使用我的超复杂POCO对象并将其作为动态传递给Postal Email类。它起作用了。

现在我想要一些webservice发送电子邮件,所以我需要将序列化数据传递给它。我发送了一封测试电子邮件,我看到电子邮件中没有出现某些字段的值,但是&#39; DynamicJsonObject&#39;相反。所以我假设(错误的),反序列化对象的结构以某种方式被破坏。

但事实是不同的:

缺少的数据是复杂类型,比如说

public class Money 
{
    public double Amount {get; set;}
    public string Currency {get; set;}

    public override ToString()
    {...}
}

所以当我在Razor电子邮件模板中询问:

@item.Prices.SalePriceGross本地,

它必须以某种方式使用ToString()方法。 当然,在序列化/反序列化的对象中,不了解ToString()方法。

我需要使用我想要显示的字符串公开一个属性,或者(更好地)显式访问AmountCurrency并在Razor电子邮件模板中处理它们。

感谢您的帮助。