in Dev

Typ object mit der WCF übermitteln

Manchmal kann es sinnvoll sein, die Schnittstelle eines Services möglichst generisch zu halten und deshalb als Datentyp object zu definieren. Die Übermittlung des Typs object ist in der WCF aber nicht unproblematisch. Es gilt dabei zu beachten, dass der Absender wie auch der Empfänger in diesem Fall .NET einsetzen müssen und beide die gleichen Typendefinitionen und Versionen referenzieren.

Die Idee: Der Absender serialisiert vor dem Versenden ein beliebiges Objekt in ein byte[]. Das Array wird anschliessend übertragen und auf der Gegenseite wieder in object umgewandelt. So lassen sich beliebige Daten übertragen so lange diese serialisierbar sind. Der Vorteil der unten stehenden Lösung besteht nun darin, dass während der Entwicklung normal gegen object programmiert werden kann. Die Umwandlung in ein byte[] für die Übertragung geschieht durch die Implementierung der [OnSerializing] und [OnDeserialized] Methoden automatisch.


using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace FlennyNET.LearningWCF.DataContract
{
    [Serializable]
    [DataContract(Name = "DemoDataContainer",
        Namespace = "http://flenny.wordpress.com/2012/02/03/typ-object-in-der-wcf/",
        IsReference = true)]
    public class CfleDemoDataContainer
    {
        [DataMember(Order = 1, Name = "Key")]
        public string Key { get; set; }

        // Hier kann ein beliebiger CLR-Typ untergebracht werden.
        // Das Property wird nicht mit dem DataMemberAttribut dekoriert.
        public object Data { get; set; }

        // Die WCF serialisiert/ deserialisiert das Objekt vor und nach der Übertragung
        // in ein byte[].
        [DataMember(Order = 2, Name = "Data")]
        private byte[] _abyteData;

        // Serialisiert das object Data in ein byte[].
        [OnSerializing]
        private void OnSerializing(StreamingContext context)
        {
            using (MemoryStream objStream = new MemoryStream())
                {
                    BinaryFormatter objFormatter = new BinaryFormatter();
                    objFormatter.Serialize(objStream, Data);

                    _abyteData = objStream.ToArray();
                }
         }

        // Deserialisiert das byte[] zurück nach object.
        [OnDeserialized]
        private void OnDeserialized(StreamingContext context)
        {
            using (MemoryStream objStream = new MemoryStream())
                {
                    objStream.Write(_abyteData, 0, _abyteData.Length);
                    objStream.Seek(0, SeekOrigin.Begin);
                    BinaryFormatter objFormatter = new BinaryFormatter();

                    Data = objFormatter.Deserialize(objStream);
                 }
        }
    }
}

Ein Visual Studio 2010 Beispielprojekt kann hier heruntergeladen werden.