Tzot

We must accept finite disappointment, but we must never lose infinite hope. -- Mattin Luther King
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

WCF学习笔记----服务契约(Service Contracts)

Posted on 2009-01-06 22:46  Tzot  阅读(1118)  评论(0编辑  收藏  举报

更新时间:2009-01-06

源代码

服务契约(Service Contracts)

ServiceContract– 定义服务操作

应用于接口或者类中,并使用接口(或类)上的 ServiceContractAttribute 属性定义服务协定。
• 建议应用于接口中
– 消除服务实现的耦合性
– 服务可能会实现多于1个契约,也就是说方便一个类的实现可以继承于多个服务契约的接口。如果将契约置于具体类上,那就不能实现继承多个契约,受制于c#类的单继承

MSDN备注:使用 ServiceContractAttribute 修饰的接口或类还必须至少拥有一个用 OperationContractAttribute 属性标记的方法以公开任意功能。

Name,指定 WSDL <portType> 元素中的协定名称。

Namespace指定 WSDL <portType> 元素中的命名空间。

SessionMode,指定协定是否需要支持会话的绑定。

ConfigurationName,指定要使用的配置文件中的服务元素的名称。

CallbackContract,指定双向(双工)对话中的返回协定。

HasProtectionLevel 和ProtectionLevel指示是否所有支持协定的消息都具有一个显式 ProtectionLevel 值,如果有,处于什么级别。

 

-------------------------------------解决方案------------------------------------------------------

image

 

-------------------------------------服务契约------------------------------------------------------

   /// <summary>
/// 人员管理接口
/// </summary>
// Namespace - 服务契约的命名空间,在WSDL中体现。
// Name - 服务契约的名称,在WSDL中体现。
// ConfigurationName - 服务契约在宿主中所配置的服务名称(默认情况下本例为类的全名“TZOT.WCF.Contract.IPersonManagerService”)
[ServiceContract(Namespace="http://www.cnblogs.com/netlife",
Name="PersonManager",
ConfigurationName="PersonManagerConfig")]
public interface IPersonManagerService
{
/// <summary>
/// 获取某人的姓名
/// </summary>
/// <param name="person">Person对象</param>
/// <returns>对应的名字</returns>
// Name - 操作契约的名称(会对应到相关的wsdl,默认情况下本例为方法名“GetName”)
[OperationContract(Name = "GetPersonName")]
string GetName(Person person);
}

-------------------------------------数据契约------------------------------------------------------

   /// <summary>
/// Person的实体类
/// </summary>
// Name - 数据契约的名称(会对应到相关的wsdl,默认情况下本例为类名“Person”)
[DataContract(Name = "PersonModel")]
public class Person
{
/// <summary>
/// Person的实体类的Age属性
/// </summary>
// Name - 数据成员的名称(会对应到相关的wsdl,默认情况下本例为属性名“Age”)
// IsRequired - 该值指示序列化引擎该成员在读取或反序列化时必须存在
// Order - 数据成员在相关的wsdl中的顺序
// EmitDefaultValue - 如果应该在序列化流中生成成员的默认值,则为 true,否则为 false,默认值为 true
[DataMember(Name = "PersonAge", IsRequired = false, Order = 1)]
public int Age { get; set; }
/// <summary>
/// Person的实体类的Name属性
/// </summary>
// Name - 数据成员的名称(会对应到相关的wsdl,默认情况下本例为属性名“Name”)
// IsRequired - 该值指示序列化引擎该成员在读取或反序列化时必须存在
// Order - 数据成员在相关的wsdl中的顺序
// EmitDefaultValue - 如果应该在序列化流中生成成员的默认值,则为 true,否则为 false,默认值为 true
[DataMember(Name = "PersonName", IsRequired = false, Order = 0)]
public string Name { get; set; }
}

-------------------------------------Hosting App.Config------------------------------------------------------

<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpGetEnabled="true" httpGetUrl=""/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="TZOT.WCF.BusinessServices.PersonManagerService" behaviorConfiguration="serviceBehavior">
<endpoint address="" contract="PersonManagerConfig" binding="basicHttpBinding"/>
<!--contract= 是服务契约中配置的ConfigurationName “PersonManagerConfig”,为我们在服务契约中配置的代码。-->
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/PersonManagerService/" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>

-------------------------------------启动服务------------------------------------------------------

    class Program
{
static void Main(string[] args)
{
//提供服务的主机
ServiceHost personManagerServiceHosting = null;
try
{
personManagerServiceHosting = new ServiceHost(typeof(PersonManagerService));
personManagerServiceHosting.Open();
Console.WriteLine();
Console.WriteLine("Press <ENTER> to terminate Host");
Console.ReadLine();
}
finally
{
personManagerServiceHosting.Close();
}
}
}

-------------------------------------客户端App.Config------------------------------------------------------

<client>
<endpoint address="http://localhost:8000/PersonManagerService/"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_PersonManager"
contract="PersonManagerSerivceRefrence.PersonManager" name="BasicHttpBinding_PersonManager" />
</client>

-------------------------------------客户端添加服务自动生成的部分代码------------------------------------------------------

可以发现自动生成的接口名字为“PersonManager ”,即在服务契约中Name="PersonManager"的体现。

可以发现自动生成的命名空间为Namespace=http://www.cnblogs.com/netlife

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://www.cnblogs.com/netlife", ConfigurationName="PersonManagerSerivceRefrence.PersonManager")]
public interface PersonManager {
[System.ServiceModel.OperationContractAttribute(Action="http://www.cnblogs.com/netlife/PersonManager/GetPersonName", ReplyAction="http://www.cnblogs.com/netlife/PersonManager/GetPersonNameResponse")]
string GetPersonName(TZOT.WCF.Client.PersonManagerSerivceRefrence.PersonModel person);
}