18

With the new C# record types in C# 9 i'd like to know wheter it is possible (for serialization) to set the JsonPropertyAttribute from Newtonsoft.Json on the constructor parameter. It doesn't seem to work out of the box.

MWE:

using System;
using Newtonsoft.Json;

Console.WriteLine(JsonConvert.SerializeObject(new Something("something")));

record Something([JsonProperty("hello")] string world) {}

Output:

{"world":"something"}

Expected output:

{"hello":"something"}

is there an easy way to make it work like this? or do we have to revert back to the property style with a real constructor?

internal record Something
{
    public Something(string world) { World = world; }

    [JsonProperty("hello")] public string World { get; }
}
Isitar
  • 1,286
  • 12
  • 29

1 Answers1

49

Per the docs:

Attributes can be applied to the synthesized auto-property and its backing field by using property: or field: targets for attributes syntactically applied to the corresponding record parameter.

So you want

record Something([property:JsonProperty("hello")] string world) {}

Without the property: qualifier, the attribute ends up on the parameter of the generated constructor (which is useful in other scenarios, like nullability).

Jeroen Mostert
  • 27,176
  • 2
  • 52
  • 85
  • In my latest VS19 preview, without `property:` compilation breaks with ie `Attribute 'JsonIgnore' is not valid on this declaration type. It is only valid on 'property, indexer, field' declarations.` – kofifus May 03 '21 at 23:58
  • 1
    @kofifus: sure, but that has nothing to do with the syntax as such, but that `JsonIgnore` has an `AttributeUsage` attribute that prohibits use on parameters. Whether or not that's allowed is specific per attribute. – Jeroen Mostert May 04 '21 at 07:26