So veranlassen Sie ServiceStack, ein expando-Objekt mit den richtigen Typen zu serialisieren / zu deserialisieren

Ich versuche nur herauszufinden, wie gut servicestack.text das Serialisieren von Expando-Objekten von und nach JSON unterstützt. Ich weiß, dass ein expando-Objekt ein IDictionary implementiert. Wenn ich zu und von json serialisiere, habe ich Probleme, die richtigen Typen im deserialisierten IDictionary zu finden. Da Json keine nativen Typen unterstützt und servicestack die Einstellung JsConfig.IncludeTypeInfo hat, erwartete ich, dass die Typinformationen in den serialisierten Json aufgenommen werden, damit der Service-Stack die Deserialisierung auf die richtigen Typen auf der anderen Seite durchführen kann (z. B. eine Dezimalstelle ohne Dezimalstellen) wird zu einem uint64 deserialisiert).

Gibt es eine Möglichkeit, ServiceStack zu zwingen, dieselben Typen wie die Quelle mithilfe eines expando-Objekts korrekt zu deserialisieren?

Ps: Ich möchte kein Poco-Objekt verwenden, um dies zu erreichen, da ich die Eigenschaften des Objekts erst zur Laufzeit kenne.

Unten ist ein kurzer Test, der zeigt, was ich meine.

Vielen Dank

/// <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");


}

Antworten auf die Frage(2)

Ihre Antwort auf die Frage