|
三、运用服务
为了运行这个服务,你还需要做一些细节工作。首先,你必须更改Service.svc文件以指向新的类和接口。在该文件中,找到下面一行:
| <span class="pf">Class="MyService" | 把它改变为:
| <span class="pf">Class="TransactableTemperatures</span>" | 下一步,配置运行时刻以允许事务;否则,运行该服务将引起一个错误。为此,从一个命令行提示符上发出如下命令:
Xws_reg --wsat+
该命令配置MSDTC以处理WS-Atomic事务(WSAT)。
当然在最后,你需要编辑web.config文件以为你的服务配置serviceModel设置。完整的web.config文件看上去如下样子:
<?xml version="1.0"?> <configuration xmlns= "http://schemas.microsoft.com/.NetConfiguration/v2.0"> <system.serviceModel> <services> <service type="TransactableTemperatures"> <endpoint contract="ITransactableTemperatures" binding="wsHttpBinding" bindingConfiguration="Binding1"/> </service > </services > <bindings> | 图2.运行服务:该图显示出从一个浏览器中运行示例事务性服务的结果。
<wsHttpBinding> <binding configurationName="Binding1" transactionFlow="true" /> </wsHttpBinding> </bindings> </system.serviceModel> <system.web> <compilation debug="true"> <assemblies> <add assembly="System.Transactions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/> </assemblies> </compilation> </system.web> </configuration> | 修改完web.config后,运行该服务将产生如图2所示的屏幕快照。
 图2.运行服务-该图显示出示例事务性服务从一个浏览器中运行的结果。 | 四、为该服务构建一客户端
当服务可用时,你可以把一个Windows表单客户应用程序添加到工程上。表单布局如图3所示;当然你也可以只使用下载版本。
 图3.设计客户-该图显示出Visual Studio表单设计器中的Windows表单客户应用程序。 | 用户把一个值输入到该文本框中,并使用单选按钮选择一个转换方法,然后点击Convert按钮来调用该服务。但是在创建相应的代码之前,你需要创建到该服务的一个代理。为此,使用下面在服务页面上的指令(见图2)-使用svcutil.exe工具来生成一个代理文件和一个客户配置文件。从我的试验看出,不使用生成的配置文件(名叫output.config)更为容易些;而是,只创建你自己的版本-它仅使用当前应用程序要求的部分,并命名它为App.config。
为运行svcutil.exe,可以从一个命令行提示符上运行下列命令:
Scvutil <url of service>?wsdl
前面的命令创建了两个文件-它们可能的命名为tempuri.org.cs和output.config。其中tempura.org.cs文件包含你需要用于调用你的服务的代理,因此现在把它添加到你的Windows客户工程。
接下来,把一个命为App.config的新文件添加到该工程并为其创建如下内容:(为简化起见,这些是output.config中的过滤结果)
<?xml version="1.0" encoding="utf-8" ?> <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0"> <system.serviceModel> <client> <endpoint configurationName="default" address= "http://atlas/TransactableService/Service.svc/" binding="wsHttpBinding" bindingConfiguration="Binding1" contract="ITransactableTemperatures"/> </client> <bindings> <wsHttpBinding> <binding configurationName="Binding1" transactionFlow="true" /> </wsHttpBinding> </bindings> </system.serviceModel> </configuration> | 现在,你可以设置btn_Click事件处理器来调用该事务性服务-使用如下的一个事务性范围:
private void btnConvert_Click(object sender, EventArgs e){ using(TransactableTemperaturesProxy theProxy = new TransactableTemperaturesProxy("default")) { TransactionOptions transactionOptions = new TransactionOptions(); transactionOptions.IsolationLevel =IsolationLevel.ReadCommitted; using ( TransactionScope tx = new TransactionScope( TransactionScopeOption.RequiresNew,transactionOptions)) { double d = Convert.ToDouble(txtIn.Text); double dResult = 0.0D; if (rbCToF.Checked) dResult = theProxy.ctof(d); else dResult = theProxy.ftoc(d); lblOut.Text = dResult.ToString(); tx.Complete(); } } } | 前面的代码首先使用缺省的配置文件名建立代理。你可以看到这是在App.config内的配置文件名。
接下来,该代码创建一个新的为IsolationLevel.ReadCommitted(匹配服务IsolationLevel设置,如前面所讨论的)而配置的transactionOptions集合。
最后,该代码在{}块中创建一个新的名叫tx的TransactionScope,这样以来发生在该块中的每一件事情都在这个tx范围内被事务化。该块中的最后一行代码把tx标志设置为Complete,并且该事务成功结束。
事务在任何相连接的系统中都是极其重要的。直到现在,开发者往往把事务与数据库方法相提并论,但是如今事务也能够良好地应用于其它类型的操作。在任何相连接的系统中,在一个工作流中传递的消息能够大大地受益于事务性。当把一些健壮的,企业级的基础结构放置到一起时,在你的代码中提供可事务性的服务至关重要。所以,事务性是WCF中最重要的支柱之一。
在本文中,你看到了怎样构建一个简单的事务性服务以及怎样从一个Windows表单客户程序中消费它。尽管这个例子只涉及到可能性的一点皮毛,但是它应该能够让你理解如何为你的客户构建和提供事务性软件服务!上一页 [1] [2] |