3

I can create JObject

var jobject = Newtonsoft.Json.Linq.JObject.Parse(jsonstring);

I want to convert the jobject read only so that no new keys can be added or existing values modified.

Rohit
  • 3,610
  • 7
  • 45
  • 76
  • 1
    What is the scope of `jobject`? Would [C# public variable as writeable inside the class but readonly outside the class](http://stackoverflow.com/a/4662190/1115360) be of use to you? – Andrew Morton Oct 28 '15 at 18:37
  • @AndrewMorton I do not control the JObject class. I can write a wrapper around it but it will not be trivial. – Rohit Oct 28 '15 at 18:40
  • 1
    You don't need to alter the JObject class, rather, just control the access to that `jobject` instance. Or are you saying that *all* instances of JObject must be read-only? – Andrew Morton Oct 28 '15 at 18:50
  • @AndrewMorton not all but I do not understand how to control access without writing a wrapper class. – Rohit Oct 28 '15 at 18:53
  • You can throw an exception in [`JObject.PropertyChanging`](http://www.newtonsoft.com/json/help/html/E_Newtonsoft_Json_Linq_JObject_PropertyChanging.htm) and [`JContainer.ListChanged`](http://www.newtonsoft.com/json/help/html/E_Newtonsoft_Json_Linq_JContainer_ListChanged.htm), but the latter happens *after* the change, so it's too late. – dbc Oct 28 '15 at 19:05

2 Answers2

2

It can't be done. There is an open issue for implementing it:

https://github.com/JamesNK/Newtonsoft.Json/issues/468

But it is two years old and has drawn very little attention as far as I can tell.

Mårten Wikström
  • 11,074
  • 5
  • 47
  • 87
2

An immutable object is one that can't be changed. If you don't want consumers of your JObject to change it, just give them a copy. (Note: this example uses the abstract superclass JToken of JObject to provide a more general solution.)

private JToken data = JToken.Parse(@"{""Some"":""JSON""}");

public JToken Data()
{
   return data.DeepClone();
}

public JToken Data(string path)
{
   return data.SelectToken(path).DeepClone();
}

The consumer will be able to change their copy, but not the source.

If data is so large that cloning it is prohibitive, use the second method JToken Data(string path) to grab a subset.