您的位置:首页 > 其它

WCF学习笔记(三)使用(Service)KnownType标记实现继承、多态特性

2011-09-19 00:09 435 查看
1.服务器端:

/// <summary>

/// 实现IExtensibleDataObject接口,表示这个类的派生类也可以序列化

/// IsRequired表示该属性是否需要赋值之后才能序列化

///

/// 注意:此类上没有标记KnownType属性,于是在客户端找不到School的派生类

/// 若是在此类上没有KnownType标记,在契约接口上使用ServiceKnownType标记也是可以的

/// 当然,ServiceKnownType标记也是可以应用在接口里面的方法上面的

/// </summary>

[DataContract(Name = "SchoolEntity", Namespace = "http://schemas.yoyo/zhu")]

//[KnownType(typeof(Teacher))]

//[KnownType(typeof(Student))]

public class School : IExtensibleDataObject

{

/// <summary>

/// 学校编号

/// </summary>

[DataMember(Name = "Num", IsRequired = true, Order = 0)]

public string s_Num { get; set; }

/// <summary>

/// 学校名称

/// </summary>

[DataMember(Name = "Name", IsRequired = true, Order = 1)]

public string s_Name { get; set; }

/// <summary>

/// 描述

/// </summary>

[DataMember(Name = "Description", IsRequired = false, Order = 2)]

public string s_Description { get; set; }

private ExtensionDataObject extensionDataObject;

#region IExtensibleDataObject 成员

public ExtensionDataObject ExtensionData

{

get

{

return extensionDataObject;

}

set

{

extensionDataObject = value;

}

}

#endregion

}

派生类:

[DataContract(Namespace = "http://schemas.yoyo/zhu")]

public class Student : School

{

public Student()

{

this.s_SchoolDerivedClass = SchoolEnmu.Student;

}

}

[DataContract(Namespace = "http://schemas.yoyo/zhu")]

public class Teacher : School

{

public Teacher()

{

this.s_SchoolDerivedClass = SchoolEnmu.Teacher;

}

}

2.契约

[ServiceContract(Name = "IKonwTypeService", Namespace = "http://www.yoyo/zhu")]

[ServiceKnownType(typeof(Teacher))]

[ServiceKnownType(typeof(Student))]

public interface IKonwTypeService

{

[OperationContract]

void AddTeacher(School sc);

[OperationContract]

List<School> GetTeacher();

}

//这个ServiceBehavior可有可无

//[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]

public class KonwTypeService : IKonwTypeService

{

private static School school;

#region IKonwTypeService 成员

public void AddTeacher(School sc)

{

school = sc;

}

public List<School> GetTeacher()

{

List<School> list = new List<School>();

list.Add(school);

return list;

}

#endregion

}

3.宿主环境配置:

ServiceHost host = new ServiceHost(typeof(KonwTypeService));

host.Open();

Console.WriteLine("宿主服务已启动!");

Console.ReadKey();

<system.serviceModel>

<services>

<service name="KonwTypeServices.KonwTypeService" behaviorConfiguration="serviceBehavior">

<host>

<baseAddresses>

<add baseAddress="http://localhost:8044"/>

</baseAddresses>

</host>

<endpoint address="KonwTypeService" contract="KonwTypeServices.IKonwTypeService" binding="basicHttpBinding" />

<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />

</service>

</services>

<behaviors>

<serviceBehaviors>

<behavior name="serviceBehavior">

<serviceMetadata httpGetEnabled="true"/>

</behavior>

</serviceBehaviors>

</behaviors>

</system.serviceModel>

4.客户端(引用服务的方式见WCF学习笔记(二))

5.注意:当ServiceKnownType和KnownType标记都没使用时,可以在配置文件里面添加如下代码,在客户端也能生成其派生类

<system.runtime.serialization>

<dataContractSerializer>

<declaredTypes>

<add type="EntityModel.School, EntityModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">

<knownType type="EntityModel.Student, EntityModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />

<knownType type="EntityModel.Teacher, EntityModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />

</add>

</declaredTypes>

</dataContractSerializer>

</system.runtime.serialization>

小结:

KnowType表示:在WCF中一个继承类可以转换成其父类,加上这个标签后,父类也可以转成子类,从而保留多态性。同时,客户端还不会生成子类的相应信息。

ServiceKnowType:当提供的服务中有参数是上面提及的父类,为了把这个父类的派生类带出来,于是需要在接口上面使用ServiceKnowType指定其派生类。当只需要在某个方法上面使用该父类的派生类,就可

以在该方法的上面使用ServiceKnowType指定即可。

在WCF中,继承的接口和类是反映不到客户端的,因此说WCF牺牲了OO的继承和多态的特性。但是这种特性可以使用已知类型的方式弥补。

源代码下载地址:http://download.csdn.net/detail/yoyoshaoye/3614453
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐