519

I have some data in a C# DataSet object. I can serialize it right now using a Json.net converter like this

DataSet data = new DataSet();
// do some work here to populate 'data'
string output = JsonConvert.SerializeObject(data);

However, this uses the property names from data when printing to the .json file. I would like to change the property names to be something different (say, change 'foo' to 'bar').

In the Json.net documentation, under 'Serializing and Deserializing JSON' → 'Serialization Attributes' it says "JsonPropertyAttribute... allows the name to be customized". But there is no example. Does anyone know how to use a JsonPropertyAttribute to change the property name to something else?

(Direct link to documentation)

Json.net's documentation seems to be sparse. If you have a great example I'll try to get it added to the official documentation. Thanks!

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
culix
  • 10,188
  • 6
  • 36
  • 52
  • 5
    FYI, there is an example of this in the documentation under [Samples -> Serializing JSON -> JsonPropertyAttribute name](http://james.newtonking.com/json/help/?topic=html/JsonPropertyName.htm). Not sure at what point it was added. – Brian Rogers Nov 10 '13 at 04:28

4 Answers4

919

You could decorate the property you wish controlling its name with the [JsonProperty] attribute which allows you to specify a different name:

using Newtonsoft.Json;
// ...

[JsonProperty(PropertyName = "FooBar")]
public string Foo { get; set; }

Documentation: Serialization Attributes

Martin Brown
  • 24,692
  • 14
  • 77
  • 122
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • 2
    Does this require that I read my data into a custom object that I create rather than a DataSet? – culix Jan 09 '12 at 23:41
  • 4
    @culix, yes, it does require using a model. A DataSet is a weakly typed structure, so talking about property names for it is not very logical. – Darin Dimitrov Jan 10 '12 at 06:50
  • 97
    As a shorthand, you can also do `[JsonProperty("FooBar")]` – Bart Verkoeijen Feb 16 '15 at 05:49
  • 4
    @DarinDimitrov is there a way to do this without Json .NET ? – CH81 Dec 31 '15 at 17:39
  • 16
    Using a model is easy though, just take a sample of your JSON and Paste it into an empty .cs file using "Paste Special" -> "Paste JSON as Classes". -- It's built in to Visual Studio. -- From there, you basically just need to set things up as title case / rename stuff to use .NET naming conventions, etc. (using a title case converter for the former, and the JsonProperty attribute for the latter). – BrainSlugs83 Oct 24 '16 at 23:36
  • 1
    This won't work if your Json object class is in another class library that uses a different version of Newtonsoft.Json package. (it may not even throw any error). In this case a `DefaultContractResolver` would be a solution, if put in the same assembly where JsonConvert.Serialize() method is used. – Artemious Jan 29 '18 at 23:29
  • 2
    For a more generic way to do this that doesn't depend on Json.NET (and that will still work with Json.NET), you can use `DataMemberAttribute` like `[DataMember(Name = "some_custom_string)]`. Most serializers, including the built in Microsoft serializers, know how to handle this attribute. – Ryan Apr 04 '18 at 02:43
  • 1
    Use `[JsonProperty(nameof(FooBar))]` to avoid the string. It could help avoid mistakes when refactoring. – Homer Feb 04 '20 at 17:23
  • 3
    @Homer That wouldn't work in this case, since the point is to be able to use a name different from the member. – Trisibo Jul 29 '20 at 03:46
  • 1
    Just [JsonProperty("FooBar")] where FooBar is the JSON property name can also be written. Its a shorthand. – sam Nov 07 '20 at 02:14
  • Is this still valid with the build in >net core serialzier? – Zapnologica Mar 23 '23 at 07:30
103

If you don't have access to the classes to change the properties, or don't want to always use the same rename property, renaming can also be done by creating a custom resolver.

For example, if you have a class called MyCustomObject, that has a property called LongPropertyName, you can use a custom resolver like this…

public class CustomDataContractResolver : DefaultContractResolver
{
  public static readonly CustomDataContractResolver Instance = new CustomDataContractResolver ();

  protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
  {
    var property = base.CreateProperty(member, memberSerialization);
    if (property.DeclaringType == typeof(MyCustomObject))
    {
      if (property.PropertyName.Equals("LongPropertyName", StringComparison.OrdinalIgnoreCase))
      {
        property.PropertyName = "Short";
      }
    }
    return property;
  }
}

Then call for serialization and supply the resolver:

 var result = JsonConvert.SerializeObject(myCustomObjectInstance,
                new JsonSerializerSettings { ContractResolver = CustomDataContractResolver.Instance });

And the result will be shortened to {"Short":"prop value"} instead of {"LongPropertyName":"prop value"}

More info on custom resolvers here

Luke Girvin
  • 13,221
  • 9
  • 64
  • 84
StingyJack
  • 19,041
  • 10
  • 63
  • 122
  • 3
    This is a better solution if your class to serialize is declared in another assembly that includes a different version of Newtonsoft.Json package. (it may not even throw any error). The `DefaultContractResolver` must be put in the same assembly where JsonConvert.Serialize() method is used. – Artemious Jan 29 '18 at 23:32
  • 2
    I'm working with an vendor's API that has a common object that is used by multiple API functions. In only one of the API calls, one property on the common object must be serialized to a slightly different name (e.g. clientid versus client_id). This answer was the perfect solution to my problem. – quaabaam Dec 08 '20 at 19:21
8

There is still another way to do it, which is using a particular NamingStrategy, which can be applied to a class or a property by decorating them with [JSonObject] or [JsonProperty].

There are predefined naming strategies like CamelCaseNamingStrategy, but you can implement your own ones.

The implementation of different naming strategies can be found here: https://github.com/JamesNK/Newtonsoft.Json/tree/master/Src/Newtonsoft.Json/Serialization

JotaBe
  • 38,030
  • 8
  • 98
  • 117
  • 5
    If you're able, please share an example of a custom NamingStrategy implementation – user1007074 Dec 10 '18 at 17:36
  • 2
    Of course... not. You should have done it by yourself, but I'll spare you the time to tell you that you simply have to inherit https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Serialization_NamingStrategy.htm You can see the existing classes implementation, and create your own one. – JotaBe Dec 11 '18 at 11:09
  • 4
    Thanks - I should have updated my comment: in fact, thanks to the glory that is GitHub, one can use one of Newtonsoft's own implementations as an example, say, [this one](https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Serialization/SnakeCaseNamingStrategy.cs) – user1007074 Dec 11 '18 at 16:34
  • 23
    @JotaBe, that's not the spirit of stackoverflow. And as a programmer who just wants to get my job done, frankly, it would have been a thousand times better for me to to lift the code you might have provided. And you would have got my vote as well. I have 18 years coding experience, and I'm ranked by TripleByte as "expert" in c#. Not EVERY problem needs to be left as an "exercise for the reader". Sometimes we just want to do our job and move on. – bboyle1234 Apr 02 '19 at 00:52
  • 5
    I agree with you, and I don't usually write this kind of comment. However, I can assure that, in this case, looking at the linked code is way better than any explanation I can give. And json.net is a very well documented open source library. Included link to the implementations (perfect examples) – JotaBe Apr 02 '19 at 14:54
3

You can directly use

[JsonProperty(Name = "access_token")]
public string AccessToken { get; set; }

or

[JsonProperty("access_token")]
public string AccessToken { get; set; }

and serialize using Newthonsoft.Json library will be detect how change it

Mohammad
  • 921
  • 7
  • 15