Anything about Programming

Focus on .NET Framework , ASP.NET , WCF

 

学习笔记:使用Web Service Software Factory开发简易留言本服务以及Mobile调用实现-1.创建Service

最近研究的头昏脑热,所以之前的WSSF学习笔记作废,现在重写~

关于Web Service Software Factory:

Web Service Software Factory是微软的开源Software Factory项目,使用WSSF可以很方便的为分布式项目提供Asmx WebService或者WCF Service的专业架构生成设计。

更多WSSF的相关资料,请查询:

http://www.microsoft.com/china/msdn/library/architecture/WebServiceFactory.mspx?mfr=true

http://www.codeplex.com/servicefactory

要开发WSSF的话,VS2005就可以了,需要安装Web Service Software Factory Feb 2006 Refresh

不过现在最新版本已经更新到Feb 2008 Modeling Edition ,可以在VS2008下进行开发,需要安装最新版本的GAX

PS:在VS2008的这个版本下,原先的Data Access Guidance Package已没有集合在当中,因此若需要生成业务实体以及数据访问层的CRUD过程,数据库操作对象的话,请同时安装Repository Factory(这个就是原先的Data Access,现在已从WSSF分离出去,作为独立的项目开发)。下载及更多信息,请访问CodePlex:Repository Factory For VS2008

学习WSSF的话,现在网上的资料并不多,版本也跟不上,如果跟着官方的15min WalkthroughHands on Lab 走一遍的话,会是不错的选择。建议学习之前先去了解WCF.对WCF的A,B,C等概念有了基本认识后,才能清楚明白的使用WSSF来开发自己的Service,并且更有助于我们对WCF的理解.

===============================

现在我们尝试使用WSSF来开发一套基本的留言本服务,并且使用Mobile Client来对它进行测试调用:

Let's go ,

#0.创建/设计数据库

先简单实现一个GuestMessage数据表的操作,我们如下设计:

#1.创建项目:

启动Vs2008 , 新建项目,选择项目类型为Guidance Packages --> Service Software Factory:Modeling Edition --> Model Project,给项目命名为"GuestBookSolution".

 

#2.构建Data Contract Model

在这一步当中,我们先对GuestMessage进行数据契约的设计。

点选项目导航视图,右键点击GuestBookSolution(有个带颜色的小图标,不是Solution),点选Add --> New Model --> Data Contract Model.

窗口中,输入你为Data Contract Model的命名以及名称空间,ok下一步

GuestMessage契约参照我们实现设计好的数据库:

设计过程中,我们通过对Data Contract添加简单类型来设置GuestMessage的各个成员,需要添加其他对象时,则需要添加一个DataContract,并用Aggregation工具将二者联系起来。对于各个成员,我们需要在属性当中设置Type来指定它们的数据类型。同时,可以为空值的成员,我们可以通过设置Properties中的Is Nullable来指定。

添加一个GuestMessageCollection的数据契约集合(Data Contract Collection),作为GuestMessage的集合对象。并用Aggregation或者设置GuestMessageCollection的Data Contract属性为GuestMessage来建立二者的关系:

同时,创建一个Fault Contract,处理在服务的方法中产生的失败。这个契约将在后面构建服务契约时用到:

最终如图:

#3.构建服务契约

这一步当中,我们对服务契约进行设计,创建一个服务,并且在这个服务的服务契约中,设计GuestMessage的添加和获取方法。

点选项目导航视图,右键点击GuestBookSolution,点选Add --> New Model --> Service Contract Model.

弹出的窗口中,为建立的服务契约模型命名为"GuestMsgServiceModels",填写名称空间。

首先,我们添加一个Service,命名为GuestMessageService,并添加一个IGuestMessage服务契约,用Connector工具为二者建立联系:

 

现在,在视图中拖两个operation contract,分别命名为AddGuestMessage和RetrieveGuestMessages,使用Connector工具将他们与IGuestMessage服务契约联系起来:

 

这样就表明,我们在IGuestMessage服务契约中,声明了两个接口方法,也就是Operation Contract,分别实现添加一个消息和获取所有消息。现在我们对两个方法进行详细设计:指定Response和Request,并设置Fault Contract.

方法的ResponseMessage和RequestMessage,我们需要将方法与Message Contract建立联系,同时在Message Contract中设置传入和传出的对象。这里我们使用Message,首先拖一个Message作为AddGuestMessage的传入消息,然后为它添加一个Data Contract Message Part,设置名称为GuestMessage,并设置它的属性,关联到我们事先在构建数据契约模型时的GuestMessage数据契约。同理,也给RetrieveGuestMessages方法添加一个ResponseMessage,添加一个数据契约的消息部分,设置类型为我们在数据契约模型中设计的GuestMessageCollection

结果如图:

 

现在为两个方法各添加一个Data Contract Fault,设置对象类型为我们在数据契约模型中添加的MessageFault.

 

OK,在建立Service之前最重要的两部完成了,现在我们来试着实现我们设计的Service,并且生成代码。

 

#4.建立WCF Service项目

右键点Solution,选择添加项目,项目类型选择Guidance Package -> Service Factory:Modeling Edition -> WCF Implementation Projects,为项目命名为"GuestBookWCFService",点击确定添加WSSF自动生成的WCF Service项目;

这里注意,如果我们的文件名过长,添加项目就会失败。。因此尽量在短路径的目录下创建项目或不要给项目起太长的名字

生成后,我们可以观察一下WSSF为我们构造的项目结构。

其中,Business Logic当中包含了BusinessEntities和BussinessLogic两个项目,这里将会包含我们设计业务逻辑的或者使用Repository Factory生成的业务实体类等等。Resource Access当中包含了DataAccess项目,这个项目将包含我们的数据访问类和存储过程等内容。Service Interface目录下的内容则是我们的WCF Service的主要内容,主要包括了各个契约以及服务的实现几个项目,我们目前所设计的模型的生成代码也将主要生成到这些项目当中。每个项目都有个GeneratedCode目录,生成的代码都将输出到这个目录中。

现在我们就来实现我们的服务并生成代码。

打开GuesgMsgDataModels.datacontract,点击空白区域,在属性视图中,我们设置Implementation Technology为WCF Extension,Project Mapping Table为GuestBookWCFService。

现在各个模型上将多出一些为WCF提供的属性,我们选择GuestMessageCollection,设置Collection Type为Collection<T>.

现在右键点击空白区域,点选Order All Data Members

现在我们将发现,数据契约GuestMessage当中的所有成员被自动排序了,因为在WCF Service中,要求数据契约的每个数据成员,都需要设置不同的Order属性。通过这个操作我们能很方便的自动为每个数据契约的成员自动排序。

现在数据契约模型的设计完毕,我们可以右键点击空白区域,点击“Generate Code”来生成代码了。生成完毕后,我们可以观察DataContract等项目下的GeneratedCode目录下,就会有WSSF为我们自动生成的数据契约。

现在打开GuestMsgServiceModels.servicecontract,同样的点击空白区域,在属性视图中,我们设置Implementation Technology为WCF Extension,Project Mapping Table为GuestBookWCFService。并且设置Serializer Type为DataContractSerializer。

然后,设置两个Message模型的IsWrapped属性为true,表明在消息当中允许换行。

一切完成后,我们可以右键点击空白区域,点击“Generate Code”生成代码。现在可以发现在ServiceContract下以及ServiceImplementation项目下将会生成我们设计的服务契约以及一个服务实现:

 

Code
using System;
using WCF = global::System.ServiceModel;

namespace GuestBookWCFService.ServiceImplementation
{
/// <summary>
/// Service Class - GuestMessageService
/// </summary>
[WCF::ServiceBehavior(Name = "GuestMessageService",
Namespace
= "urn:Dannies.GuestBookWCFService",
InstanceContextMode
= WCF::InstanceContextMode.PerSession,
ConcurrencyMode
= WCF::ConcurrencyMode.Single )]
public abstract class GuestMessageServiceBase : GuestBookWCFService.ServiceContracts.IIGuestMessage
{
#region IGuestMessage Members

public virtual void AddGuestMessage(GuestBookWCFService.MessageContracts.RequestMessage request)
{

}

public virtual GuestBookWCFService.MessageContracts.RespondMessages RetrieveGuestMessages()
{
return null;
}

#endregion

}

public partial class GuestMessageService : GuestMessageServiceBase
{
}

}

 

当这些都成功完成后,现在就可以将我们的Service应用部署到我们的host测试项目上了

 

#5.部署WCF Service

点选项目导航视图,右键点击GuestBookSolution(有个带颜色的小图标,不是Solution),点选Add --> New Model --> Host Model.

命名为“GuestMsgHost.host”,输入名称空间创建。打开GuestMsgHost.host。

现在切换到Host Explorer,我们会发现这样的视图:

右键点击Host Model,选择Add New Host Application.这样在Host Applications下将会生成一个Host配置。现在我们对Host进行配置:

设置这个Host Application的属性,名称为GuestMessageHost,Implementation Project选择我们在创建WCF Implementation Projects时生成的测试Host项目“\GuestBookSolution\GuestBookWCFService\Tests\GuestBookWCFService.Host”,设置Implementation Technology为WCF Extension.

右键点击GuestMessageHost,选择Add New Service Reference,为服务添加一个引用.点选这个服务,设置属性:名称设置为GuestMessageService,Service Implementation Type选择我们在服务契约模型中创建的GuestMessageService服务。另外设置Enable Metadata Publishing为True,使我们的服务支持Metadata发布。

最后,再为这个服务添加一个EndPoint,设置属性:名称为DefaultEndpoint,BindingType设置为默认的basicHttpBinding.

这里也可以设置为wsHttpBinding。但由于我们需要给Mobile Client提供服务,而Mobile Client只支持basicHttpBinding的WCF服务。而这也就是说,我们将无法使用WCF所支持的事务,回调,可靠性传输等特性与Mobile客户端交互。

完成后,我们点击在视图中点选GuestMessageService,在大视图中将出现一个Generate Service的链接,我们点击这个链接即可完成具体服务的配置和部署到我们的测试Host项目,也就是我们设置的Implementation Project:

 

注意,这里存在一个Bug。很多朋友知道我们可以使用WCF Service Config Editor来配置WCF服务。如果我们使用这个工具作为默认打开Config的工具的话,这一步中配置文件的生成将要失败

生成完毕之后,我们需要重新编译下所有的项目,右键点选解决方案,选择Rebuild Solution。

现在我们试着看一下我们的Service是否生成成功。选择生成的测试Host项目,View in Browser.

在跳出的窗口中选择GuestMessageService.svc,如果生成成功了,我们将看到我们的Service已成功发布。我们可以点击页面上的链接来看我们生成的服务的服务描述:

 

WSDL:
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions name="GuestMessageService" targetNamespace="urn:Dannies.GuestBookWCFService" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:tns="urn:Dannies.GuestBookWCFService" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex">
<wsdl:types>
<xsd:schema targetNamespace="urn:Dannies.GuestBookWCFService/Imports">
<xsd:import schemaLocation="http://localhost:17400/GuestBookWCFService.Host/GuestMessageService.svc?xsd=xsd0" namespace="urn:Dannies.GuestBookWCFService"/>
<xsd:import schemaLocation="http://localhost:17400/GuestBookWCFService.Host/GuestMessageService.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="RequestMessage">
<wsdl:part name="parameters" element="tns:RequestMessage"/>
</wsdl:message>
<wsdl:message name="IGuestMessage_AddGuestMessage_OutputMessage"/>
<wsdl:message name="IGuestMessage_AddGuestMessage_MessageFaultFault_FaultMessage">
<wsdl:part name="detail" element="tns:MessageFault"/>
</wsdl:message>
<wsdl:message name="IGuestMessage_RetrieveGuestMessages_InputMessage"/>
<wsdl:message name="RespondMessages">
<wsdl:part name="parameters" element="tns:RespondMessages"/>
</wsdl:message>
<wsdl:message name="IGuestMessage_RetrieveGuestMessages_MessageFaultFault_FaultMessage">
<wsdl:part name="detail" element="tns:MessageFault"/>
</wsdl:message>
<wsdl:portType name="IGuestMessage">
<wsdl:operation name="AddGuestMessage">
<wsdl:input wsaw:Action="urn:Dannies.GuestBookWCFService.IGuestMessage.AddGuestMessage" name="RequestMessage" message="tns:RequestMessage"/>
<wsdl:output wsaw:Action="urn:Dannies.GuestBookWCFService/IGuestMessage/AddGuestMessageResponse" message="tns:IGuestMessage_AddGuestMessage_OutputMessage"/>
<wsdl:fault wsaw:Action="urn:Dannies.GuestBookWCFService/IGuestMessage/AddGuestMessageMessageFaultFault" name="MessageFaultFault" message="tns:IGuestMessage_AddGuestMessage_MessageFaultFault_FaultMessage"/>
</wsdl:operation>
<wsdl:operation name="RetrieveGuestMessages">
<wsdl:input wsaw:Action="urn:Dannies.GuestBookWCFService.IGuestMessage.RetrieveGuestMessages" message="tns:IGuestMessage_RetrieveGuestMessages_InputMessage"/>
<wsdl:output wsaw:Action="urn:Dannies.GuestBookWCFService/IGuestMessage/RetrieveGuestMessagesResponse" name="RespondMessages" message="tns:RespondMessages"/>
<wsdl:fault wsaw:Action="urn:Dannies.GuestBookWCFService/IGuestMessage/RetrieveGuestMessagesMessageFaultFault" name="MessageFaultFault" message="tns:IGuestMessage_RetrieveGuestMessages_MessageFaultFault_FaultMessage"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="DefaultEndPoint" type="tns:IGuestMessage">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="AddGuestMessage">
<soap:operation soapAction="urn:Dannies.GuestBookWCFService.IGuestMessage.AddGuestMessage" style="document"/>
<wsdl:input name="RequestMessage">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="MessageFaultFault">
<soap:fault name="MessageFaultFault" use="literal"/>
</wsdl:fault>
</wsdl:operation>
<wsdl:operation name="RetrieveGuestMessages">
<soap:operation soapAction="urn:Dannies.GuestBookWCFService.IGuestMessage.RetrieveGuestMessages" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="RespondMessages">
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="MessageFaultFault">
<soap:fault name="MessageFaultFault" use="literal"/>
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="GuestMessageService">
<wsdl:port name="DefaultEndPoint" binding="tns:DefaultEndPoint">
<soap:address location="http://localhost:17400/GuestBookWCFService.Host/GuestMessageService.svc"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

 

现在我们的WCF Service已经成功生成。下面我们将使用Repository Factory来生成业务实体以及Data Access的数据库操作逻辑。

I'll Come Up the Article Recently , Thanks~:)

 

posted on 2008-12-03 18:11  Dani Shan  阅读(3037)  评论(7编辑  收藏  举报

导航