0

I'm trying to just serialize settable properties using Json.NET. I have a custom ContractResolver and am trying to ignore readonly properties using the Writable property of a JsonProperty class.

The test below fails. I would expect that the property is 'Writable = true' because there is only a 'get' definition on the property Bar.

Is there another way of doing this?

As a side note, the reason for serializing this way is that it will save a lot of unnecessary properties serializations. The source and destination object will be the same, so there's not much point in loading up the json with unnecessary properties.

     [TestClass]
            public class JsonDotNet_WriteOnlyTests
            {
                private class FooContractResolver : DefaultContractResolver
                {
                    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
                    {
                        IList<JsonProperty> properties = base.CreateProperties(type, MemberSerialization.Fields);

                        //ignore all readonly properties
                        var readOnlyProps = properties.Where(w => !w.Writable);
                        foreach (var readonlyProp in readOnlyProps)
                        {
                            readonlyProp.Ignored = true;
                        }

                        return properties;
                    }
                }

                private class Foo
                {
                    public string Name { get; set; }

//I would expect this property to be 'Writable=false'...
                    public string Bar { get { return "Hey there"; } }
                }

                [TestMethod]
                public void TestWriteOnly()
                {
                    var settings = new JsonSerializerSettings
                    {
                        ContractResolver = new FooContractResolver()
                    };

                    var foos = new []{new Foo{}, new Foo{}};

                    var json = JsonConvert.SerializeObject(foos, settings);

                    Assert.IsFalse(json.Contains("Bar"));
                }
            }
BlackjacketMack
  • 5,472
  • 28
  • 32
  • I'm understand that this 'should' be a duplicate. The problem is, that when I run my tests the property 'Bar' is included. In other words, it's considered 'Writable' when it shouldn't be. Maybe it's the version of Json.NET (Version 6.0.8) I'm using? If you run my test (plop it in an MSTEST if you could) does it pass (great!) or fail(bummer)? – BlackjacketMack Sep 18 '15 at 20:38
  • I changed how I input 'MemberSerialization' to mirror the duplicate question and it works. Funny though how the property would still get registered as a JsonProperty writable the way I've written above. – BlackjacketMack Sep 18 '15 at 20:40
  • After running through it a couple of times, I think this is a bug in Json.NET. The MemberSerialzation value passed into base.CreateProperties should simply limit the returned JsonProperty objects...not change whether or not a given JsonProperty is Writable. – BlackjacketMack Sep 18 '15 at 20:53
  • While I cannot explain the reasoning behind why passing `MemberSerialization.Fields` to `CreateProperties` results in read-only properties being marked as writable, it seems to be quite intentional, according what's in the source code. See [line 1199 of the DefaultContractResolver class](https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs#L1199) and the comment two lines above it. Bottom line, if you don't want that behavior, don't pass `MemberSerialization.Fields` to `CreateProperties`. – Brian Rogers Sep 19 '15 at 04:23

0 Answers0