Search code examples
c#asp.netjson.net

.NET Newtonsoft Allow property to be only serialised


I have implemented the answer from this (rather old) question https://stackoverflow.com/a/31732029/4180176 but it doesn't seem to work for me and I can't figure out why.

I can indeed see that property.Writable gets set to false. The property I mark as not serializable gets put as the last field in the output json but is always present

Startup.cs

services.AddControllers().AddNewtonsoftJson(opt =>
{
  opt.UseMemberCasing();
  opt.SerializerSettings.ContractResolver = new NewtonsoftContractResolver();
});

Contract Resolver

[AttributeUsage(AttributeTargets.Property)]
public class DoNotSerializeAttribute : Attribute
{

}

public class NewtonsoftContractResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        var property = base.CreateProperty(member, memberSerialization);

        if (property is not null && property.Writable)
        {
            var attributes = property.AttributeProvider.GetAttributes(typeof(DoNotSerializeAttribute), true);

            if (attributes is not null && attributes.Count > 0)
            {
                    property.Writable = false;
            }
        }    
        return property;
    }
}

Attribute Usage

public class LeaderboardUser : RankedObject
{
    [JsonProperty("UserID")]
    [DoNotSerialize]
    public string UserID { get; set; }
}

Solution

  • serialization

    var leaderBoardUser = new LeaderboardUser { UserID = "userId", UserName = "userName" };
    var json = JsonConvert.SerializeObject(leaderBoardUser);
    

    result

    {"UserID":"userId","UserName":"userName"}
    

    deserialization

    leaderBoardUser = JsonConvert.DeserializeObject<LeaderboardUser>(json);
    

    result

    UserID  null
    UserName    userName
    

    class

    public partial class LeaderboardUser
    {
        public string UserID { get; set; }
        public string UserName { get; set; }
    
        [JsonConstructor]
        public LeaderboardUser(string UserId)
        {
    
        }
        public LeaderboardUser()
        {
    
        }
    }