Serializacja obiektów

0

Witam podczas serializacji obiejtu dostaję wyjątek: "The type B was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.". Odnalezione matieruały do XmlInclude i SoapInclude nie rozwiązały problemu. Dopiero zakomentowana linijka z tworzeniem nowego obiektu prowadzi do prawidłowej serializacji obiektu, ale wydaje się to strasznie nadmiarowe i zapewne zbędne.

    public class A
    {
        public string PropA { get; set; }
    }

    public class B : A
    {
        public string PropB { get; set; }
    }

    public class Obj
    {
        [System.Xml.Serialization.XmlElement(ElementName = "ObjA", Type = typeof(A))]
        public A ObjA { get; set; }

        public string Serialize()
        {
            // this.ObjA = new A() { PropA = this.ObjA.PropA };

            var xSerializer = new System.Xml.Serialization.XmlSerializer(typeof(Obj));
            try
            {
                using (var mStream = new System.IO.MemoryStream())
                {
                    using (var sWriter = new System.IO.StreamWriter(mStream))
                    {
                        xSerializer.Serialize(sWriter, this);

                        sWriter.Flush();
                    }

                    return System.Text.Encoding.UTF8.GetString(mStream.ToArray());
                }
            }
            catch(Exception ex)
            {

            }

            return string.Empty;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Obj o = new Obj();
            o.ObjA = new B() { PropB = "PropB" };
            o.ObjA.PropA = "PropA";

            string s = o.Serialize();
        }
    }
0

Dodanie atrybutu nie jest nadmiarowe.
Powiedzmy że chcesz teraz ten Xml zdeserializować w innej aplikacji albo w innej platformie (Java, PHP). W drugim programie też musisz mieć zarówno typ A jak i B. Skąd teraz drugi programista ma wiedzieć, że we właściwości o typie A może występować B? Z dokumentacji. Taką dokumentacją może być plik WSDL. Pisanie go ręcznie jest trudne i podatne na błędy, więc lepiej go wygenerować. Skąd generator ma wiedzieć jakie typy mogą być podstawione pod B? Może oczywiście przejrzeć solucję i podstawić wszystkie typy dziedziczące po B jednak wtedy może ujawnić typy, które nigdy nie opuszczą serwisu (a mogą zawierać dane wrażliwe). Więc najlepiej powiedzieć generatorowi wprost: "W miejscu A może wystąpić B".

0

A jak użyłeś tego XmlInclude?

    [XmlInclude(typeof(B))]
    public class A
    {
        public string PropA { get; set; }
    }

Po dodaniu atrybutu jak powyżej działa poprawnie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1