0

I've used the built-in Visual Studio menu option "Paste Special->Paste JSON as classes" selection on a JSON string that contains dots in the names of fields. (Example: System.Title).

The generated class has the dots removed (understandably) from the property names in the class (From the above example, System.Title = SystemTitle). Here is a snippet of an example of the JSON that I am trying to deserialize (from Microsoft TFS REST APIs):

 {
    "id": 27736,
    "rev": 6,
    "fields": {
      "System.WorkItemType": "Test Case",
      "System.State": "Ready",
      "System.Reason": "Completed",
      "System.Title": "EFCValuesTest_DenomNotPresent",
      "Microsoft.VSTS.Common.StateChangeDate": "2019-02-14T21:15:37.627Z",
      "Microsoft.VSTS.Common.ActivatedDate": "2019-01-25T20:25:52.743Z",
      "Microsoft.VSTS.Common.Priority": 4,
    },
  },

Notice that although CamelCase is used, there are also dot (.) name separators as well.

When I try to deserialize the fields JSON segment into the class object, the values are not extracted. However, if I place a JsonProperty attribute with the PropertyName set to the name with dots such as [JsonProperty(PropertyName = "System.Title")], then Json.NET can resolve the name and assign the correct value upon deserialization.

Is there any way to have Json.NET do this name-lookup conversion automatically without having to assign the JsonProperty to all of the class properties that are associated with fields that have dots in the name?

Ken
  • 72
  • 8
  • Does this answer your question? [How to apply a general rule for remapping all property names when serializing with Json.NET?](https://stackoverflow.com/q/46476903/3744182). Take `CustomNamingStrategy` from the [accepted answer](https://stackoverflow.com/a/46477576/3744182), change `char wordBreakChar = '.';` and remove `sb.Replace("Number", "#");` – dbc Jul 23 '20 at 20:40
  • Demo fiddle of using the answer from [How to apply a general rule for remapping all property names when serializing with Json.NET](https://stackoverflow.com/q/46476903/3744182) here: https://dotnetfiddle.net/sUGyGv. You can also set the naming strategy in settings by setting it in a contract resolver as shown in [this answer](https://stackoverflow.com/a/48652197/3744182) to [Newtonsoft JsonConvert.SerializeObject ignoring JsonProperty if name is uppercase](https://stackoverflow.com/q/48647650/3744182). – dbc Jul 23 '20 at 22:10
  • This seems a bit more complicated than I anticipated. At first I thought that using a custom naming strategy class might work, but after looking it over I am not sure I can use it because the dot naming convention used in the JSON is a mixture of dot and CamelCase. I really need to know the JSON field name and then just remove the dots from it to match it to the class property name (which is in CamelCase). Seems like using the NamingStrategy approach works off of translating the class property name to the JSON field name, which is a bit more challenging in my case. – Ken Jul 24 '20 at 15:29
  • [Custom contract resolvers](https://www.newtonsoft.com/json/help/html/contractresolver.htm#CustomIContractResolverExamples) and naming strategies control how a c# class is serialized to JSON, and are generated from the class itself via reflection. There isn't anything that generates a contract from JSON **in runtime**, rather than from a class. Can you please [edit] your question to provide a [mcve]? Incidentally Json.NET deserialization is case-insensitive so if you are only deserializing, camel casing is harmless. – dbc Jul 24 '20 at 15:33
  • I added an example snippet of the JSON that I am trying to deserialize. Notice how there is mix of dots and CamelCase so I can't just use a CamelCase converter. – Ken Jul 24 '20 at 19:11
  • But the naming seems to be consistent based on specific type being deserialized, right? So you could apply `[JsonObject(NamingStrategyType = typeof(CustomNamingStrategy))]` to your `Fields` class, and that should work. Or are you saying that you want to embed JSON sample strings in your app and somehow look up in the embedded JSON to find the appropriate JSON name for a given c# name? – dbc Jul 24 '20 at 19:15
  • Or do you want Json.NET to do some sort of regex match on incoming JSON property names to find the most likely c# property match? – dbc Jul 24 '20 at 19:16
  • I'm still a little confused by your requirement here, but do you still want this to be reopened? There might be some tricks possible with deserialization (by stripping the `.` off at the `JsonTextReader` level) but I don't see how you could **serialize** your classes and add the `.` into the names without adding `JsonProperty` and/or `[JsonObject(NamingStrategyType = typeof(CustomNamingStrategy))]` attributes. – dbc Jul 24 '20 at 22:26
  • What I want is to be able to have something similar to the CutomNamingStrategy approach, but be able to translate the JSON names to C# property names, not the other way around. It seems like it would be easier to receive the JSON name and just strip out the dots to match it to the C# property names during deserialization.. – Ken Jul 27 '20 at 12:05
  • I have a feeling that my best course of action is to use JsonProperty attribute and just specify the appropriate JSON name for each C# property. – Ken Jul 27 '20 at 12:09
  • *It seems like it would be easier to receive the JSON name and just strip out the dots to match it to the C# property names during deserialization.* -- but your question title is *How to **serialize** / deserialize json with dots in names*. Is serialization actually not required after all? Because if only deserialization is required then there are options. – dbc Jul 27 '20 at 14:18
  • For instance you could use `PropertyNameMappingJsonReader` from [this answer](https://stackoverflow.com/a/47539562/3744182) to [Change key name of data loaded through JsonExtensionData](https://stackoverflow.com/q/47529655/3744182) to strip the `.` characters out of the incoming property names. – dbc Jul 27 '20 at 14:21
  • 1
    I need both Serialization and Deserialization, so I guess it wouldn't be feasible to rely solely on the JSON name, especially if sending a request. Like I said earlier, it seems like JsonProperty is the way to go in my case. So, you can keep this request closed. – Ken Jul 27 '20 at 18:08

0 Answers0