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

sniperd
  • 5,124
  • 6
  • 28
  • 44

3 Answers3

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.

TypeIA
  • 16,916
  • 1
  • 38
  • 52
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

Stringfellow
  • 2,788
  • 2
  • 21
  • 36
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).

galdin
  • 12,411
  • 7
  • 56
  • 71
  • This won't work, the `$id` and `$type` properties are special values. – DavidG May 30 '18 at 16:25
  • @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...? :)) – DavidG May 30 '18 at 16:53
  • Always good to learn new things, and there's always more to learn! – DavidG May 30 '18 at 17:08
  • @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. – TypeIA May 30 '18 at 17:28