Forum Cross Platform with Xamarin

Portable class library and serialization issue

Hi, I have an issue about portable class library. Please check the attached project which throws an exception when we run it.
1, If we get rid of [OnSerializing] attribute from the portable library things would be fine.
2, If we run with iOS and Android platform, it works fine, but in some different link mode, it won’t call this method. For example compiling with linking “All” mode.

Is that an issue in Xamarin? Did anyone have this same issue and is there any clue to work this around?

Posts

  • SKallSKall USMember ✭✭✭✭

    Can you try if adding the OnSerializing call to constructor would make a difference? If it does then the explanation is simple...the linker removes OnSerializing method since it is not directly referenced anywhere. This should happen on iOS with the AOT compiler and Link All settings.

        public Student(string name, int age)
        {
            Name = name;
            Age = age;
    
            this.OnSerializing(null);
        }
    

    ...

        private void OnSerializing(StreamingContext context)
        {
            if (context == null)
            {
                return;
            }
    
            Debug.WriteLine("Student OnSerializing");
        }
    
  • Hi Skall,

    Thanks for your quick reply. Calling OnSerializing method in constructor doesn’t fix my issue. Because we need to interfere in before and after serialization and de-serialization. For example, we have a class A, it has a B field whose type is marked as “SerializableAttribute”. We want to serialize this instance with BinaryFormatter. In normal situation, it will failed because of B type is not “Serializable”. So to work around it, we need to create a wrapper _B for B type. _B is marked as “Serializable”.
    In the “OnSerializing” method, we will create _B instance by B, then BinaryFormatter will serialize _B instead. On the OnDeserialized, the BinaryFormatter will de-serialize _B instance, we can get this wrapper instance and create B instance manually to complete this entire serialization and de-serialization without lose any states. There are some other reasons but this should be a major one. Hope that makes sense.

    We considered to use DataContractAttribute, but it will be a huge project for us. I think if we could fix the issue that represents in the previous attached sample, I think we could smoothly transfer our project to PCL.

  • JGoldbergerJGoldberger USMember, Forum Administrator, Xamarin Team, University Xamurai

    I believe the issue here is that [OnSerializing] and the [Serializable] attributes are used with BinaryFormatter which is not in the PCL .NET Portable profile. Unfortunately I think you will have to use DataContract and DataContractSerializer instead.

    See: http://stackoverflow.com/a/20872983/2913599

    and: http://stackoverflow.com/questions/12903262/portable-class-library-recommended-replacement-for-serializable

    I hope this helps!

  • I agree to use DataContract is better recently. But we have two reasons to use SerializableAttribute.

    1, Our existing project is huge and if we use DataContract instead, it might take lots of side effect and we might need to take long time to correct it.

    2, As far as I know, to serialize and de-serialize a DataContract instance needs to indicate known types if this class has a complex type. So that we cannot cover all the cases, but the BinaryFormatter can.

    So those two reasons prevent us from using DataContractAttribute.

  • SKallSKall USMember ✭✭✭✭

    How big is the data? Serializing to non-binary formats (such as XML and JSON) could be done without DataContract attributes as long as the getters and setters are public (and with some serializers even without public setter).

  • BenBaiBenBai USMember

    After more test, here is what I found (guess):

    1. Portable Core is not supposed to support Serializable attribute, DataContractor is the recommended way.
    2. The BinaryFormatter works if there is no [OnSerializing] Attribute in Portable Core library, because
    • You implemented the SerializableAttribute in the portable library by yourself
    • BinaryFormatter thinks the SerializableAttribute you implemented is somehow compliant with the one in .NET framework. It still surprises me that BinaryFormatter accepts the SerializableAttribute you made.
  • The BinaryFormatter doesn’t work when [OnSerializing] Attribute is decorated because
    • OnSerializingAttribte has been implemented in portable core, and there is no way for us to create another one with the same name.
    • BinaryFormatter apparently doesn’t like the OnSerializing attribute in portable core. The “Type 'XXX' in assembly 'YYY' has method 'OnSerializing' with an incorrect signature for the serialization attribute that it is decorated with.” shows it is a method not compatible exception.

    So in a word, BinaryFormatter is not supposed to work with Portable Core. We make it work by creating our own [Serializable] Attribute classes. But as OnSerializable Attribute is already in portable core which is not compliant with BinaryFormatter, we cannot use it.

  • bartholmberg.2426bartholmberg.2426 USMember, University

    Any idea when the binary formatter/[Serializable] will be implemented in the Portable Core?

  • howardchen.6880howardchen.6880 USMember ✭✭

    Have no idea yet. But we workaround it by removing OnSerializingAttribute in our portable project. And it could be successfully serialized in the iOS or Android project.

  • vahidshirzadivahidshirzadi USMember

    how can i use binary serialization in xamarin form?
    sharpserializer doesn't work

  • Sign In or Register to comment.