WCF数据契约代理和已知类型的使用

using Bll;
using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace Distributed.Model
{
    #region 1.1 已知类型KnownType [KnownType(typeof(T))]

    [DataContract]
    //[KnownType(typeof(Bar))]
    //[KnownType(typeof(Baz))]
    public class Foo
    {
    }
    [DataContract]
    public class Bar : Foo
    {
    }
    [DataContract]
    public class Baz : Bar
    {
    }
    #endregion

    #region 1.2 KnownType 指定方法名 GetKnownTypes
    //[DataContract]
    //[KnownType("GetKnownTypes")]
    //public class Foo
    //{
    //    public static IEnumerable<Type> GetKnownTypes()
    //    {
    //        yield return typeof(Bar);
    //        yield return typeof(Baz);
    //    }

    //} 
    #endregion

    #region 2. ServiceKnownType指定解析类KnownTypeResolver和方法GetKnownTypes
    [ServiceContract(Namespace = "www.holworth.com")]
    [ServiceKnownType("GetKnownTypes", typeof(KnownTypeResolver))]
    public interface IContract
    {
        [OperationContract]
        void DoSomething(Foo foo);

    }
    public static class KnownTypeResolver
    {
        public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider provider)
        {
            yield return typeof(Bar);
            yield return typeof(Baz);
        }
    }
    #endregion

    [DataContract]
    public class Contract
    {
        [DataMember]
        public string FullName { get; set; }
        [DataMember]
        public string Sex { get; set; }
    }
    [DataContract]
    public class Custmoer
    {
        [DataMember]
        public string FirstName { get; set; }
        [DataMember]
        public string LastName { get; set; }
        [DataMember]
        public string Gender { get; set; }

    }
    /// <summary>
    /// 目标进入契约对象,出来也是契约对象
    /// </summary>
    public class ContractSurrogate : IDataContractSurrogate
    {
        public Type GetDataContractType(Type type)
        {
            if (type == typeof(Contract))
            {
                return typeof(Custmoer);
            }
            return type;
        }
        /// <summary>
        /// obj
        /// </summary>
        /// <param name="obj">obj是序列化之后的对象,我们的目标是反序列化得到原始类型Contract</param>
        /// <param name="targetType"></param>
        /// <returns></returns>
        public object GetDeserializedObject(object obj, Type targetType)
        {
            Custmoer customer = obj as Custmoer;
            if (customer == null)
            {
                return obj;
            }
            return new Contract()
            {
                FullName = customer.FirstName + " " + customer.LastName,
                Sex = customer.Gender
            };
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj">原始契约对象类型Contract</param>
        /// <param name="targetType"></param>
        /// <returns></returns>
        public object GetObjectToSerialize(object obj, Type targetType)
        {
            Contract contract = obj as Contract;
            if (contract == null)
            {
                return obj;
            }
            return new Custmoer()
            {
                FirstName = contract.FullName.Split(" ".ToCharArray())[0],
                LastName = contract.FullName.Split(" ".ToCharArray())[1],
                Gender = contract.Sex
            };
        }
        public void GetKnownCustomDataTypes(Collection<Type> customDataTypes)
        {

        }

        public object GetCustomDataToExport(Type clrType, Type dataContractType)
        {
            return null;
        }

        public object GetCustomDataToExport(MemberInfo memberInfo, Type dataContractType)
        {
            return null;
        }
        public Type GetReferencedTypeOnImport(string typeName, string typeNamespace, object customData)
        {
            return null;
        }
        public CodeTypeDeclaration ProcessImportedType(CodeTypeDeclaration typeDeclaration, CodeCompileUnit compileUnit)
        {
            return typeDeclaration;
        }

    }

    public class Program
    {
        public static void Serializer<T>(T instance, string fileName, IDataContractSurrogate dataContractSurrogate)
        {
            DataContractSerializer serializer = new DataContractSerializer(typeof(T), null, int.MaxValue, false, false, dataContractSurrogate);
            using (XmlWriter writer = new XmlTextWriter(fileName, Encoding.UTF8))
            {
                serializer.WriteObject(writer, instance);
                Process.Start(fileName);
            }
        }
        public static T Deserializer<T>(string fileName, IDataContractSurrogate dataContractSurrogate)
        {
            DataContractSerializer serializer = new DataContractSerializer(typeof(T), null, int.MaxValue, false, false, dataContractSurrogate);
            using (XmlReader reader = new XmlTextReader(fileName))
            {
                return (T)serializer.ReadObject(reader);
            }

        }
        public static void Host()
        {
            using (ServiceHost serviceHost = new ServiceHost(typeof(BasCurrencyService)))
                foreach (ServiceEndpoint ep in serviceHost.Description.Endpoints)
                {
                    foreach (OperationDescription op in ep.Contract.Operations)
                    {
                        DataContractSerializerOperationBehavior dataContractBehavior = op.Behaviors.Find<DataContractSerializerOperationBehavior>() as DataContractSerializerOperationBehavior;
                        if (op.Behaviors.Find<DataContractSerializerOperationBehavior>() != null)
                        {
                            dataContractBehavior.DataContractSurrogate = new ContractSurrogate();
                        }
                        op.Behaviors.Add(op.Behaviors.Find<DataContractSerializerOperationBehavior>());
                        dataContractBehavior = new DataContractSerializerOperationBehavior(op);
                        dataContractBehavior.DataContractSurrogate =new ContractSurrogate();
                        op.Behaviors.Add(dataContractBehavior);
                    }
                }
        }
        public static void main(string[] args)
        {
            //1.1 实验输出
            string fileName = "contract.xml";
            Contract contract = new Contract() { FullName = "ke xiangbin", Sex = "Male" };
            IDataContractSurrogate dataContractSurrogate = new ContractSurrogate();
            Serializer<Contract>(contract, fileName, dataContractSurrogate);
            Console.WriteLine("序列化前");
            Console.WriteLine("	{0,-9}:{1}", "FullName", contract.FullName);
            Console.WriteLine("	{0,-9}:{1}", "Sex", contract.Sex);
            contract = Deserializer<Contract>(fileName, dataContractSurrogate);
            Console.WriteLine("反序列化后");
            Console.WriteLine("	{0,-9}:{1}", "FullName", contract.FullName);
            Console.WriteLine("	{0,-9}:{1}", "Sex", contract.Sex);
            //1.2 服务寄宿应用数据契约代理
            Host();
            Console.ReadKey();
        }
    }

}
原文地址:https://www.cnblogs.com/kexb/p/8191909.html