You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ReadOnly and WriteOnly properties aren't excluded from serialization #21
Trying to serialise/deserialise this class, messagePack fails because an exception is thrown because no setter is available.
I've noticed that while parsing members, it will take all properties or variables but doesn't filter out properties that are readonly or writeonly.
Class TestClass
Public item As String = ""
Public ReadOnly Property readonlyProperty As String
Get
Return item
End Get
End Property
Private _getSetproperty As String = ""
Public Property getSetPproperty() As String
Get
Return _getSetproperty
End Get
Set(ByVal value As String)
_getSetproperty = value
End Set
End Property
I think, in the .NET world, there is a principal that a serializer should not treat non public members unless user(developer) explicitly requires it. So MsgPack for CLI does not serialize non public members as you saw.
I guess that your use case should be covered that you mark your type with traditional [Serializable] attribute when you serialize non public type. How do you think?
I've changed my thoughts.
When a type has non-publicly-accessible members, it could have complex implementations like hashtables. So, they are not able to be handled even if the serializer just handle non-public members. It looks better that msgpack for cli adds ISerializationFormatter implementations on FCL runtime serialization stack. Although it is very rich and powerful, it is limited for platforms and performance. So, I will add new serialization formatter class in future.
Thank you for your suggestion, and it is welcome to post additional comment :)
Sorry for the delay,I'll try to explain properly my issue:
Our classes only use <XMLIgnore()> to ignore properties and readonly properties where ignored automatically by XMLSerializer/Deserializer but MessagePack doesn't. As I mentioned before, a readOnly property does reach the serialization process if none of these rules are applied to my object https://github.com/msgpack/msgpack-cli/wiki/Serialization-attributes which in my opinion they probably shouldn't unless they are marked to be included. Sorry if I'm not clear enough.
That's my point, it should ignore that property but messagePack Isn't doing so. I don't have any kind of custom metadata as described in the previous link besides XMLIgnore() in some properties which isn't the case for this specific because it's readOnly and XMLSerializer/Deserializer already ignore read-only props.
Although you cannot opt-out read only property as you see, you can do equivalent with opt-in manner like following:
ClassTestClassPublicitemAsString=""PublicReadOnlyPropertyreadonlyPropertyAsStringGetReturnitemEndGetEndProperty' ...' Mark at least one read-write members with MessagePackMemberAttribute<MessagePackMember(0)>PublicPropertyFooAsInteger...EndProperty
Not that when you use MessagePackMemberAttribute, members marked with MessagePackMemberAttribute attribute are only serialized/deserialized. Non marked members are just ignored.
If you want to serialize your immutable class, consider implementing IPackable and/or IUnpackable to customize serialization/deserialization behavior. It similar to ISerializable of .NET runtime serialization.
Thanks, I know that there is the new metadata which allow me to opt-in but unfortunately our current code base is already composed of hundreds of serializable classes and hand changing all properties to manually add the metadata is an issue. Thanks for your time.
@yfakariya: Thx - i checked the Image example - lots of cross cutting code :-( Is there a helper function which can map the array to members with [MessagePackMember(X)]?
Unfortunately, there is not. But I guess you can do it as following:
Define mutable objects for serialization. They have enough fields to serialize states for correspond immutables.
Wrap mutable objects with your immutable type, or copy from/to immutables in IPackable/IUnpackable methods.
Get the serializer instance for correspond mutable in IPackable/IUnpackable methods of immutables, then invoke its PackTo/UnpackFrom.
Following code is pseudo code of IPackable.PackTo:
publicclassMyImmutable:Ipavkable IUnpackable
{privateMyMutablestate;publicStringTheProp1{get{returnstate.TheProp1;}}// rest of getters to acomplish immutable object here...voidIPackable.PackTo(Packerpacker,PackingOptionsoptions){// note: If you use copying pattern, instantiate mutable and copy state here.// Get serializer.varserializer=MessagePackSerializer.Create<MyMutable>();// Pack mutable instead of immutable.serializr.PackTo(packer,state);}// IUnpackable members here...}
This seems like a flaw in the design. For public properties, a public getter with no (or no public) setter should have its value serialized to the msgpack content, but should not have its value set during deserialization; likewise a public setter with no (or no public) getter should have its value set during deserialization, but should not be present in the serialized content. Readonly properties need to be permitted without special attributes, etc, to allow for computed values that derive their value from other read/write fields and properties. Many other serializers work this way and mskpack should, too.
Activity
yfakariya commentedon Jan 18, 2014
I think, in the .NET world, there is a principal that a serializer should not treat non public members unless user(developer) explicitly requires it. So MsgPack for CLI does not serialize non public members as you saw.
I guess that your use case should be covered that you mark your type with traditional [Serializable] attribute when you serialize non public type. How do you think?
yfakariya commentedon Jan 23, 2014
I've changed my thoughts.
When a type has non-publicly-accessible members, it could have complex implementations like hashtables. So, they are not able to be handled even if the serializer just handle non-public members. It looks better that msgpack for cli adds ISerializationFormatter implementations on FCL runtime serialization stack. Although it is very rich and powerful, it is limited for platforms and performance. So, I will add new serialization formatter class in future.
Thank you for your suggestion, and it is welcome to post additional comment :)
yfakariya commentedon Jan 23, 2014
...and, you can opt out read-only and/or write-only members by marking members with some custom attributes. See https://github.com/msgpack/msgpack-cli/wiki/Serialization-attributes for details.
joaofernandes commentedon Jan 24, 2014
Sorry for the delay,I'll try to explain properly my issue:
Our classes only use <XMLIgnore()> to ignore properties and readonly properties where ignored automatically by XMLSerializer/Deserializer but MessagePack doesn't. As I mentioned before, a readOnly property does reach the serialization process if none of these rules are applied to my object https://github.com/msgpack/msgpack-cli/wiki/Serialization-attributes which in my opinion they probably shouldn't unless they are marked to be included. Sorry if I'm not clear enough.
mvodep commentedon Jan 26, 2014
Hmm How is it possible to serialize a readonly property either?
public string Foo { get; private set; }
Throws an exception that set is not possible
joaofernandes commentedon Jan 27, 2014
That's my point, it should ignore that property but messagePack Isn't doing so. I don't have any kind of custom metadata as described in the previous link besides XMLIgnore() in some properties which isn't the case for this specific because it's readOnly and XMLSerializer/Deserializer already ignore read-only props.
mvodep commentedon Jan 27, 2014
Hmm. Ok - i have the opposite case ;-) I would be happy if it would work in C# - it doesnt ;-( I had to make all my immutable objects public :-((
yfakariya commentedon Jan 28, 2014
Sorry for delay. I think that I spoke too soon because your needs might be satisfied with existing features.
@joaofernandes
Although you cannot opt-out read only property as you see, you can do equivalent with opt-in manner like following:
Not that when you use
MessagePackMemberAttribute, members marked withMessagePackMemberAttributeattribute are only serialized/deserialized. Non marked members are just ignored.@mvodep
If you want to serialize your immutable class, consider implementing
IPackableand/orIUnpackableto customize serialization/deserialization behavior. It similar toISerializableof .NET runtime serialization.joaofernandes commentedon Jan 28, 2014
Thanks, I know that there is the new metadata which allow me to opt-in but unfortunately our current code base is already composed of hundreds of serializable classes and hand changing all properties to manually add the metadata is an issue. Thanks for your time.
mvodep commentedon Jan 29, 2014
@yfakariya: Thx - i checked the Image example - lots of cross cutting code :-( Is there a helper function which can map the array to members with [MessagePackMember(X)]?
yfakariya commentedon Jan 30, 2014
@mvodep
Unfortunately, there is not. But I guess you can do it as following:
Following code is pseudo code of IPackable.PackTo:
mvodep commentedon Jan 31, 2014
I'll give it a try - thx :)
AaronTorgerson commentedon Jul 1, 2014
This seems like a flaw in the design. For public properties, a public getter with no (or no public) setter should have its value serialized to the msgpack content, but should not have its value set during deserialization; likewise a public setter with no (or no public) getter should have its value set during deserialization, but should not be present in the serialized content. Readonly properties need to be permitted without special attributes, etc, to allow for computed values that derive their value from other read/write fields and properties. Many other serializers work this way and mskpack should, too.
yfakariya commentedon Jul 21, 2014
@AaronTorgerson
I agree your opinion, and pr #32 and recent changes on 0.5 branch fix this design issue.