如何让ServiceStack序列化/反序列化具有正确类型的expando对象

时间:2012-12-05 05:25:26

标签: servicestack

试图弄清楚servicestack.text支持将jono对象序列化为json。我知道一个expando对象实现了一个IDictionary。当我序列化到json和从json序列化时,我无法在反序列化的IDictionary中获取正确的类型。由于Json本身不支持类型,而servicestack有一个名为JsConfig.IncludeTypeInfo的设置,我希望它在序列化的json中包含类型信息,以使服务栈能够反序列化到另一端的正确类型,(例如,没有小数位的小数)被反序列化为uint64)。

是否有强制servicestack使用expando对象正确反序列化与源相同的类型?

Ps:我不想使用poco对象来实现这一点,因为直到运行时我才知道对象的属性。

下面是一个快速测试,显示我的意思。

由于

/// <summary>
/// Test servicestack serialisation
/// I was expecting that IncludeTypeInfo=true would always add the type info
/// so when you deserialise into a IDictionary<string,object> servicerstack
/// would have enough information to convert to the expected type
/// </summary>
[Test]
public void TestDynamicSerialization()
{
    JsConfig.Reset();
    JsConfig.IncludeNullValues = true;
    JsConfig.IncludeTypeInfo = true;
    JsConfig.EmitCamelCaseNames = false;
    JsConfig.ConvertObjectTypesIntoStringDictionary = true;
    JsConfig.PropertyConvention = JsonPropertyConvention.Lenient;
    JsConfig.TryToParsePrimitiveTypeValues = true;

    // create an expando object
    dynamic obj = new ExpandoObject();

    // cast as a idictionary and set two decimals, one with decimnal places and one without
    var objDict = (IDictionary<string, object>)obj;
    objDict["decimal1"] = 12345.222M;
    objDict["decimal2"] = 12345M;

    Assert.AreEqual(typeof(decimal), objDict["decimal1"].GetType());
    Assert.AreEqual(typeof(decimal), objDict["decimal2"].GetType());

    // serialise to json
    var json = JsonSerializer.SerializeToString(obj);

    //deserialise to a a IDictionary<string,object>
    var deserialisedDict = JsonSerializer.DeserializeFromString<IDictionary<string, object>>(json);

    // make sure we got the expected types
    Assert.AreEqual(typeof(decimal), deserialisedDict["decimal1"].GetType());
    Assert.AreEqual(typeof(decimal), deserialisedDict["decimal2"].GetType(), "Fails because type is UInt64 expected decimal");


}

2 个答案:

答案 0 :(得分:1)

NuGet上的ServiceStack.Text是一个.NET 3.5 dll,并且没有对Dynamic / Expando的隐式支持。您仍然可以使用JsonObject动态解析JSON。

在ServiceStack.Text的.NET 4.0版本中,您可以使用DynamicJson来封装对Dynamic类中JSON对象的访问。

答案 1 :(得分:1)

应固定为https://github.com/ServiceStack/ServiceStack.Text/pull/347小数,默认情况下会返回,除非您指定TryToParseNumericType,在这种情况下,您将获得最合适的数字类型。