Why Are Properties Without a Setter Not Serialized

Why are properties without a setter not serialized

It's a limitation of XmlSerializer it doesn't serialize read-only properties, what you have done in your second example is essentially the hack to get it to serialize, however, it's useless if you need it to deserialize later.

Alternatively you could switch to using DataContractSerializer, it's more flexible.

Why cant I serialize a property that has a private setter (C#, json)

When you use System.Runtime.Serialization without any annotations it will ignore properties that can't be set and serialize all public members of given type that can be serialized and deserialized.

However, if you go for explicit declaration of what it should serialize, it will work:

[DataContract]
public class TestSubObject
{
[DataMember]
public string Property { get; private set; } = "Bar";
}

[DataContract]
public class TestObject
{
[DataMember]
public TestSubObject Sub { get; set; }
[DataMember]
public string Property { get; set; }
}

Output:

{
"Property": "Foo",
"Sub": {
"Property": "Bar"
}
}

Don't serialize properties with no setter

Since you can't modify the OpenTK.Vector2 struct to add [JsonIgnore] property to the get-only properties, the easiest way to do this might be to write your own JsonConverter for it:

public class Vector2Converter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(OpenTK.Vector2);
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var temp = JObject.Load(reader);
return new OpenTK.Vector2(((float?)temp["X"]).GetValueOrDefault(), ((float?)temp["Y"]).GetValueOrDefault());
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var vec = (OpenTK.Vector2)value;
serializer.Serialize(writer, new { X = vec.X, Y = vec.Y});
}
}

Then use it like:

        var settings = new JsonSerializerSettings();
settings.Converters.Add(new Vector2Converter());
Vector2 v = new Vector2 { X = 1, Y = 0 };
string json = JsonConvert.SerializeObject(v, settings);
Debug.WriteLine(json);

Which produces

{"X":1.0,"Y":0.0}

But if you really want to ignore all get-only properties everywhere on all classes and structs (which might have unforeseen consequences), see here: Is there a way to ignore get-only properties in Json.NET without using JsonIgnore attributes?.

Cannot deserialize type without setter

JSON.NET would be the answer here. You can find it in nuget. Use it like this:

JsonConvert.DeserializeObject<T>(input);

XML Serializer not serializing property which has public getter but no setter

The deserialiser is just C# code. It requires a setter for a serialised property. Thus you must have a getter and setter for every property that is to be serialised by XML serializer; it also requires the property to be public.

Also you do not need an empty constructor for the class.

[Serializable]
[XmlRoot("Task"), SoapType("Task")]
public class TaskDto : IDto
{
public int ID { get; set; }
public int TaskSequence { get; set; }
}

For more info, see http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx

Why isn't my public property serialized by the XmlSerializer?

As mentioned, most properties must have both a getter and setter; the main exception to this is lists - for example:

private readonly List<Foo> bar = new List<Foo>();
public List<Foo> Bar {get { return bar; } } // works fine

which will work fine; however, if XmlSerializer finds a setter - it demands that it is public; the following will not work:

public List<Foo> Bar {get; private set;} // FAIL

Other reasons it might not serialize:

  • it isn't public with get and set (or is readonly for a field)
  • it has a [DefaultValue] attribute, and is with that value
  • it has a public bool ShouldSerializeFoo() method that returned false
  • it has a public bool FooSpecified {get;set;} property or field that returned false
  • it is marked [XmlIgnore]
  • it is marked [Obsolete]

Any of these will cause it not to serialize

protobuf-net not serializing C# properties with private setters

Found the answer here: c# protobuf-net when deserialize the some property value always is -1

In order to save space, protobuf doesn't serialize default values for value types.
In this example, the .NET default value of a bool is false. The default constructor sets the IsEmpty property to true, and since the value I am expecting it to have is the same as the .NET default value, protobuf skips saving that value, so I get the value from the default constructor.

The fix is either setting IsRequired to TRUE, like Marc says, or to use [ProtoContract(10), DefaultValue(true)] on the parameter.

C# serializer skipping a property

Your property needs a setter to be serialized. Otherwise how would you deserialize it?

You can parse the string to DateTime and assign to ConversionDate in the setter.

Read-only model property not serialized in Web API

The default JSON serializer is now Json.NET. So readonly property serialization should work without you having to do anything at all.

For XML, in 4.5 we added this flag to the DataContractSerializer:

http://msdn.microsoft.com/en-us/library/vstudio/system.runtime.serialization.datacontractserializersettings.serializereadonlytypes.aspx

You should be able to write something like this:

config.Formatters.XmlFormatter.SetSerializer(myType, new DataContractSerializer(myType, new DataContractSerializerSettings() { SerializeReadOnlyTypes = true });

Place this code in a function called by GlobalConfiguration.Configure in the Application_Start. By default this would be WebApiConfig.Register().

Can an internal setter of a property be serialized?

If it is an option, DataContractSerializer (.NET 3.0) can serialize non-public properties:

[DataContract]
public class Person
{
[DataMember]
public int ID { get; internal set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public int Age { get; set; }
}
...
static void Main()
{
Person person = new Person();
person.Age = 27;
person.Name = "Patrik";
person.ID = 1;

DataContractSerializer serializer = new DataContractSerializer(typeof(Person));
XmlWriter writer = XmlWriter.Create(@"c:\test.xml");
serializer.WriteObject(writer, person);
writer.Close();
}

With the xml (re-formatted):

<?xml version="1.0" encoding="utf-8"?>
<Person xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://schemas.datacontract.org/2004/07/">
<Age>27</Age>
<ID>1</ID>
<Name>Patrik</Name>
</Person>


Related Topics



Leave a reply



Submit