0

I have to extract a part of json-string using .net or newtonsoft json.

JSON:

var json = "{\"method\":\"subtract\",\"parameters\":{\"minuend\":\"SOME_CUSTOM_JSON_OBJECT_DIFFERENT_FOR_EACH_METHOD\",\"subtrahend\":23}}";

C# Class:

class MyJson{
    public string method { get; set; }
    //public string parameters {get; set;}
    public object parameters {get; set;}
}
  1. I do not need to parse all the children of "parameters" json-object. "parameters" could be a very big object ([{obj1}...{obj1000}], objX of 1000 fields), parse which would be not performant. I would like i.e. to pass it exactly as it is on some point, so conversion "string-C#object-string" would be redundant.
  2. I do not want use Regexp or string transformations (string.Substring, Split and co), because of error margin, I know that all .net and newtonsoft string transformations based.

Question 1: if I define a property of type "object", how newtonsoft will handle this? (Documentation is worse than msdn, so I'm looking for the input from you, who already tried this).

static void Main(string[] args)
{
     var json = "{\"method\":\"subtract\",\"parameters\":{\"minuend\":42,\"subtrahend\":23}}";
     var data = JsonConvert.DeserializeObject<MyJson>(j);

     // what internal representaion of data.parameters?
     // How is it actually converted from json-string to an C# object (JObject/JsonObject).
}

In perfect case: "parameters" is a string and calling

ExtractMyJson(jsonString)

gives me the json string of parameters.

Basically I need the newtonsoft version of

string ExtractMyJson(jsonString){
  var p1 = jsonString.Split(",");
  // .. varios string transformations
  return pParams;
}

Note: please don't reference "dynamic" keyword or ask why no string transformations, it's the very specific question.

2
  • The question is - how big will the parameters be in the worst case? Is it really a problem? JSON.NET is pretty fast and this optimization you are thinking about might not be worth at all. Commented Feb 17, 2016 at 9:09
  • parameters: [{obj1}...{obj1000}], objX of 1000 fields Commented Feb 17, 2016 at 9:21

3 Answers 3

1

If you know that your parameters are unique you can do something like this:

class MyJson
{
    public string method { get; set; }
    public Dictionary<string,object> parameters { get; set; }
}
................
string json = "{\"method\":\"subtract\",\"parameters\":{\"minuend\":{\"img\": 3, \"real\": 4},\"subtrahend\":23}}";
var data = JsonConvert.DeserializeObject<MyJson>(json);

If you let it as object is going to receive the type Newtonsoft.Json.Linq.JObject.

Sign up to request clarification or add additional context in comments.

7 Comments

Thank you, the parameter types are unknown/complex, modified the json in question. If minuend is "{img: 3, real: 4}" instead of just "42" will it work? - nope "Unexpected character"
As long as you are using type object is going to work, because the Newtonsoft DeserializeObject function is going to cast it to JObject which is king of generic type. But if you need the content it will be hard to access it.
Yes, that's what is already mentioned in the question plus "Question 1"-part. I would like to know what is JObject and difference between parsing everything to JObject vs. strongly typed objects
JObject is a dictionary. ((JObject)data.parameters)["minuend"]["img"] is equal to 3.
Ok, this could work, and when eventually the type is known, how can we convert from object to the stronly typed type, say X {string y, int z}. It's like we have to map generic dictionary to this type X?
|
1

Have you tried JTOKEN?

It is a rather simple solution to partially read basic or nested JSONs as described in this post.

For a nested JSON

{ 
"key1": {
            "key11": "value11",
            "key12": "value12"
         }
"key2": "value2"
}

it would look like this

JToken token = JToken.Parse(json);
var value12 = token.SelectToken("key1.key12");

to get the element of the key "key12.

I think this could go nicely with your problem.

Comments

0

Well Objects are treated the same way your parent object is treated. It will start from the base of the graph. So if you have something like:

Person
{
 Address Address {get;set;}
}

The Json will start Deserializing Address and then add in the Person object. If you want to limit thesize of the graph depth you can use a setting like :

JsonConvert.DeserializeObject<List<IList<IList<string>>>>(json, new JsonSerializerSettings
 {
    MaxDepth = 2
 });

For more configurations of the JsonSerializer check JsonSerializerSettings

If your field is an object then that object will have the KeyValuePair of every property that it holds, based on that when you cast that field you can access that type.(the behaviour is the same as assigning a type to an object in C#).

Update: So if you question using JsonObject or type, well JObject is and intermediary way to construct the json format in a generic format. But using the Type deserializatin means you can ignore properties you are not interested in. Mapping to a json with a type makes more sense because it creates a new object and dismisses the old JObject.

2 Comments

Depth must not be limited, I don't have control over "parameters", I want to be able to pass them along as-is, so the cpu time cost would be minimal for me to traverse this object. Basically you say, it is impossible to do?
Then as @Alex Suleap said use a generic mapping so you can access them. public Dictionary<string,string> parameters { get; set; }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.