1

I have a JSON value like this

{"$id":"649271776","$type":"outdoorgame","Overs":50,"Balls":6,"TeamName":"TestTeam"}

I wrote a C# code like this to change the value of Overs from 50 to 10

var jsonString = sSession.GameState; //this is the value {"$id":"649271776","$type":"outdoorgame","Overs":50,"Balls":6,"TeamName":"TestTeam"}
dynamic jsonObject = 
Newtonsoft.Json.JsonConvert.DeserializeObject(jsonString);
jsonObject.Overs = 10;
var modifiedJsonString = Newtonsoft.Json.JsonConvert.SerializeObject(jsonObject);

This code is changing the value of Overs from 50 to 10. The problem I am facing when I use the above code modifiedJsonString is missing these two values

"$id":"649271776","$type":"outdoorgame"

giving the output as {Overs":10,"Balls":6,"TeamName":"TestTeam"} I want $id and $type also in the modifiedJsonString.

I want modifiedJsonString like this {"$id":"649271776","$type":"outdoorgame","Overs":10,"Balls":6,"TeamName":"TestTeam"}

Can anyone tell me how to solve this problem

11
  • Please format the JSON as well! Commented May 30, 2018 at 16:18
  • Actually JSON is correct only, I guess something has to do with $id and $type, so have to do the code differently (not sure) Commented May 30, 2018 at 16:21
  • How was the JSON serialised in the first place? Commented May 30, 2018 at 16:21
  • After modifying the overs I am Serialising like this var modifiedJsonString = Newtonsoft.Json.JsonConvert.SerializeObject(jsonObject); Commented May 30, 2018 at 16:23
  • I'm asking you so that the question is more readable! Commented May 30, 2018 at 16:24

3 Answers 3

2

The problem is that $id and $type are not valid identifiers, and can't appear as members of the returned dynamic object built by the JSON serializer. As in gldraphael's answer, the solution is to create your own concrete class to hold the deserialized object; for the properties whose names start with $ you'll need to use JsonPropertyAttribute to remap the names:

public class GameState
{
    [JsonProperty("$id")] public string ID { get; set; }
    [JsonProperty("$type")] public string Type { get; set; }
    int Overs { get; set; }
    int Balls { get; set; }
    public string TeamName { get; set; }
}

Further, Json.NET treats $type as a special property name and this interferes with proper deserialization of your object. To get around this, we must use the MetadataPropertyHandling.Ignore serializer setting.

Thus you can deserialize, modify and re-serialize like this:

string jsonString = "{\"$id\":\"649271776\",\"$type\":\"outdoorgame\",\"Overs\":50,\"Balls\":6,\"TeamName\":\"TestTeam\"}";
JsonSerializerSettings settings = new JsonSerializerSettings() { MetadataPropertyHandling = MetadataPropertyHandling.Ignore };
GameState jsonObject = JsonConvert.DeserializeObject<GameState>(jsonString, settings);
jsonObject.Overs = 10;
var modifiedJsonString = JsonConvert.SerializeObject(jsonObject);

See it in action.

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

Comments

1

You can use JToken to handle this.

using Newtonsoft.Json; using Newtonsoft.Json.Linq;

var jsonString = "{\"$id\":\"649271776\",\"$type\":\"outdoorgame\",\"Overs\":50,\"Balls\":6,\"TeamName\":\"TestTeam\"}";
JToken jsonObject = JToken.Parse(jsonString);
jsonObject["Overs"] = 10;
var modifiedJsonString = JsonConvert.SerializeObject(jsonObject);

// In case one wanted to update the $type and $id fields
jsonObject["$type"] = "asdf";
jsonObject["$id"] = 123456;
var modifiedJsonString2 = JsonConvert.SerializeObject(jsonObject);

Will result in: modifiedJsonString --> {"$id":"649271776","$type":"outdoorgame","Overs":10,"Balls":6,"TeamName":"TestTeam"}

And if you needed to update $id and $type, that is possible, too. modifiedJsonString2 --> {"$id":123456,"$type":"asdf","Overs":10,"Balls":6,"TeamName":"TestTeam"}

Demo on .NET Fiddle: https://dotnetfiddle.net/a370Mv

4 Comments

But you are just creating static values here, this doesn't keep the original values.
I am demonstrating that one can also update the $id and $type as well.
But how would you keep the original values? This code just makes up new ones.
This worked Stringfellow... I want to approve your code but I don't have the enough reputation(I am new user) so unable to approve your code. Your code worked for me. Thanks
0

Use a concrete class. You'll need to annotate the fields with $ prefixes manually. Eg:

public class Example
{
    public string Field { get; set; }

    [JsonProperty("$type")]
    public string Type { get; set; }
}

Here's a working example.

In your case the class will look something like:

public class ObjName
{
    [JsonProperty("$id")]
    public string Id { get; set; }
    [JsonProperty("$type")]
    public string Type { get; set; }
    public int Overs { get; set; }
    public int Balls { get; set; }
    public string TeamName { get; set; }
}

(Just be mindful of the property case).

4 Comments

This won't work, the $id and $type properties are special values.
@TypeIA Exactly, because they are special values used by JSON.Net which is why they occur at the start of the JSON. Look up TypeNameHandling (and are you now saying that you didn't try it out earlier...? :))
Always good to learn new things, and there's always more to learn!
@DavidG Luckily the authors did the right thing and provided an option to control this behavior. Thus, it works how we tell it to work. I have posted a more thorough answer with this information. I will also do some pollution control and delete all my previous comments here.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.