0

I have a JsonObject representing the following JSON

{
  "prop1": "text string",
  "prop2": 33,
  "prop3": true,
  "prop4": 6.3,
  "prop5": [ "A", "B", "C" ],
  "prop6": { "A" : "a" }
}

And in JInt scripting engine, there is a method getProp(name:String) : Object to query the property by its name.

So within the engine, this method is used like

var p1 = getProp('prop1');
var p2 = getProp('prop2');
var p3 = getProp('prop3');

The question is: In C# how can I convert the property into object which can be passed to Scripting Engine?

I tried JsonObject.JsonTo<object>("prop5") but it returns a string instead of an array. I can't use JsonObject.JsonTo<string[]>("prop5") because the property could be other types(string / number / object / boolean )

UPDATE:

The following ugly code is what I am using now to do the job. It is unstable because variables like "true" is coverted to boolean even if it is actually string type. The reason is that ServiceStack's JsonObject stores the data as JSV format and I don't see there is a way to convert the property back to JSON.

JsonObject properties = ...;
// this method is called from JInt script engine
public object getProp(string name)
{

    string script = properties.GetUnescaped(name);
    if (!string.IsNullOrWhiteSpace(script))
    {
        if (string.Equals(script, "true") || string.Equals(script, "false"))
        return string.Equals(script, "true");
        if (string.Equals(script, "null") || string.Equals(script, "undefined"))
        return null;
        int num1;
        if (int.TryParse(script, out num1))
        return num1;
        decimal num2;
        if (decimal.TryParse(script, out num2))
        return num2;
        if ( (script.StartsWith("[") && script.EndsWith("]")) )
        return TypeSerializer.DeserializeFromString<object[]>( script );
        if ( (script.StartsWith("{") && script.EndsWith("}")) )
        return TypeSerializer.DeserializeFromString<object>(script);

        return script;
    }

    //...
}
Mr.Wang from Next Door
  • 13,670
  • 12
  • 64
  • 97

1 Answers1

0

The reason is that ServiceStack's JsonObject stores the data as JSV format and I don't see there is a way to convert the property back to JSON.

This is incorrect, JsonObject doesn't have anything to do with the JSV Format or use its TypeSerializer implementation.

If you want to convert it into an object you can just deserialize it into a POCO that matches the shape of the json, e.g:

public class TypeObject
{
    public string Prop1 { get; set; }
    public int Prop2 { get; set; }
    public bool Prop3 { get; set; }
    public double Prop4 { get; set; }
    public string[] Prop5 { get; set; }
    public Dictionary<string,string> Prop6 { get; set; }
}

var typeObj = json.FromJson<TypeObject>();

The JsonObject class is only for manually parsing the JSON Dynamically, i.e. instead of deserializing it into a concrete type.

Here's an example of how you can use it to parse values individually using JsonObject, e.g:

var obj = JsonObject.Parse(json);
var o = new TypeObject
{
    Prop1 = obj["prop1"],
    Prop2 = obj.Get<int>("prop2"),
    Prop3 = obj.Get<bool>("prop3"),
    Prop4 = obj.Get<double>("prop4"),
    Prop5 = obj.Get<string[]>("prop5"),
    Prop6 = obj.Object("prop6"),
};
mythz
  • 141,670
  • 29
  • 246
  • 390
  • 1
    Thanks but it does not help. The input JSON is a "free" key-value map and there is no guarantee which properties it has and what types they are. The script running in JInt engine retrieves the property by specific property name. But the application has no idea what properties there will be . I tried `DynamicJson` but found it does not work in DTO when the json is sent from web browser. – Mr.Wang from Next Door Jul 22 '15 at 03:37