我的WCF之旅(1):创建一个简单的WCF程序

为了使读者对基于WCF的编程模型有一个直观的映像,我将带领读者一步一步地创建一个完整的WCF应用。本应用功能虽然简单,但它涵盖了一个完整WCF应用的基本结构。对那些对WCF不是很了解的读者来说,这个例子将带领你正式进入WCF的世界。

在这个例子中,我们将实现一个简单的计算服务(CalculatorService),提供基本的加、减、乘、除的运算。和传统的分布式通信框架一样,WCF本质上提供一个跨进程、跨机器以致跨网络的服务调用。在本例中,客户端和服务通过运行在相同的同一台机器上不同进程模拟,图1体现了客户端和服务端进程互相调用的关系。

图1 计算服务应用运行环境

WCF的服务不能孤立地存在,需要寄宿于一个运行着的进程中,我们把承载WCF服务的进程称为宿主,为服务指定宿主的过程称为服务寄宿(Service Hosting)。在我们的计算服务应用中,采用了两种服务寄宿方式:通过自我寄宿(Self-Hosting)的方式创建一个控制台应用作为服务的宿主(寄宿进程为Hosting.exe);通过IIS寄宿方式将服务寄宿于IIS中(寄宿进程为IIS的工作进行W3wp.exe)。客户端通过另一个控制台应用模拟(进程为Client.exe)。接下来,我们就一步一步来构建这样的一个WCF应用。

步骤一:构建整个解决方案

通过VS 2008创建一个空白的解决方案,添加如下四个项目。项目的类型、承载的功能和相互引用关系如下,整个项目在VS下的结构如图2所示。

  • Contracts一个类库项目,定义服务契约(Service Contract),引用System.ServiceMode程序集(WCF框架的绝大部分实现和API定义在该程序集中);
  • Services一个类库项目,提供对WCF服务的实现。定义在该项目中的所有WCF服务实现了定义在Contracts中相应的服务契约,所以Services具有对Contracts项目的引用;
  • Hosting一个控制台(Console)应用,实现对定义在Services项目中的服务的寄宿,该项目须要同时引用Contracts和Services两个项目和System.ServiceMode程序集;
  • Client一个控制台应用模拟服务的客户端,该项目引用System.ServiceMode程序集。

图2 计算服务在VS中的结构

步骤二:创建服务契约

WCF采用基于契约的交互方式实现了服务的自治,以及客户端和服务端之间的松耦合。WCF包含四种类型的契约:服务契约、数据契约、消息契约和错误契约,这里着重于服务契约。从功能上讲,服务契约抽象了服务提供的所有操作;而站在消息交换的角度来看,服务契约则定义了基于服务调用的消息交换过程中,请求消息和回复消息的结构,以及采用的消息交换模式。第4章将提供对服务契约的详细介绍。

一般地,我们通过接口的形式定义服务契约。通过下面的代码,将一个接口ICalculator定义成服务契约。WCF广泛采用基于自定义特性(Custom Attribtue)的声明式编程模式,我们通过在接口上应用System.ServiceModel.ServiceContractAttribute特性将一个接口定义成服务契约。在应用ServiceContractAttribute特性的同时,还可以指定服务契约的名称和命名空间。至于契约名称和命名空间的含义和作用,在本人拙著《WCF技术剖析(卷1)》第4章,在这里我们将契约名称和命名空间设置成CalculatorService和http://www.artech.com/)。

通过应用ServiceContractAttribute特性将接口定义成服务契约之后,接口的方法成员并不能自动成为服务的操作。在此方面,WCF采用的是显式选择(Explicit Opt-in)的策略:我们须要在相应的操作方法上面显式地应用OperationContractAttribute特性。

   1: using System.ServiceModel;
   2: namespace Artech.WcfServices.Contracts
   3: {
   4:     [ServiceContract(Name="CalculatorService", Namespace="http://www.artech.com/")]
   5:     public interface ICalculator
   6:     {
   7:         [OperationContract]
   8:         double Add(double x, double y);
   9:  
  10:         [OperationContract]
  11:         double Subtract(double x, double y);
  12:  
  13:         [OperationContract]
  14:         double Multiply(double x, double y);
  15:  
  16:         [OperationContract]
  17:         double Divide(double x, double y);        
  18:     } 
  19: }
步骤三:创建服务

当服务契约成功创建时,我们需要通过实现服务契约来创建具体的WCF服务。WCF服务CalculatorService定义在Services项目中,实现了服务契约接口ICalculator,实现了所有的服务操作。CalculatorService定义如下:

   1: using Artech.WcfServices.Contracts;
   2: namespace Artech.WcfServices.Services
   3: {
   4:    public class CalculatorService:ICalculator
   5:     {
   6:         public double Add(double x, double y)
   7:         {
   8:             return x + y;
   9:         }
  10:  
  11:         public double Subtract(double x, double y)
  12:         {
  13:             return x - y;
  14:         }
  15:  
  16:         public double Multiply(double x, double y)
  17:         {
  18:             return x * y;
  19:         }
  20:  
  21:         public double Divide(double x, double y)
  22:         {
  23:             return x / y;
  24:         }
  25:     }
  26: }

步骤四:通过自我寄宿的方式寄宿服务

WCF服务需要依存一个运行着的进程(宿主),服务寄宿就是为服务指定一个宿主的过程。WCF是一个基于消息的通信框架,采用基于终结点(Endpoint)的通信手段。终结点由地址(Address)、绑定(Binding)和契约(Contract)三要素组成,如图3所示。由于三要素应为首字母分别为ABC,所以就有了易于记忆的公式:Endpoint = ABC。一个终结包含了实现通信所必需的所有信息,我们可以这样认识终结点的ABC:

  • 地址(Address):地址决定了服务的位置,解决了服务寻址的问题,《WCF技术剖析(卷1)》第2章提供了对地址和寻址机制的详细介绍;
  • 绑定(Binding):绑定实现了通信的所有细节,包括网络传输、消息编码,以及其他为实现某种功能(比如安全、可靠传输、事务等)对消息进行的相应处理。WCF中具有一系列的系统定义绑定,比如BasicHttpBinding、WsHttpBinding、NetTcpBinding等,《WCF技术剖析(卷1)》第3章提供对绑定的详细介绍;
  • 契约(Contract):契约是对服务操作的抽象,也是对消息交换模式以及消息结构的定义。《WCF技术剖析(卷1)》第4章提供对服务契约的详细介绍。

 

图3 终结点三要素

服务寄宿的目的就是开启一个进程,为WCF服务提供一个运行的环境。通过为服务添加一个或多个终结点,使之暴露给潜给的服务消费者。服务消费者最终通过相匹配的终结点对该服务进行调用。我们可以完全通过代码的方式完成所有的服务寄宿工作,下面的代码体现了通过一个控制台应用对CalculatorService的寄宿:

   1: using System;
   2: using System.ServiceModel;
   3: using System.ServiceModel.Description;
   4: using Artech.WcfServices.Contracts;
   5: using Artech.WcfServices.Services;
   6: namespace Artech.WcfServices.Hosting
   7: {
   8:     class Program
   9:     {
  10:         static void Main(string[] args)
  11:         {
  12:             using (ServiceHost host = new ServiceHost(typeof(CalculatorService)))
  13:             {
  14:                 host.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "http://127.0.0.1:9999/calculatorservice");
  15:                 if (host.Description.Behaviors.Find<ServiceMetadataBehavior>() == null)
  16:                 {
  17:                     ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
  18:                     behavior.HttpGetEnabled = true;
  19:                     behavior.HttpGetUrl = new Uri("http://127.0.0.1:9999/calculatorservice/metadata");
  20:                     host.Description.Behaviors.Add(behavior);
  21:                 }
  22:                 host.Opened += delegate
  23:                 {
  24:                     Console.WriteLine("CalculaorService已经启动,按任意键终止服务!");
  25:                 };
  26:  
  27:                 host.Open();
  28:                 Console.Read();
  29:             }
  30:         }
  31:     }
  32: }

WCF服务寄宿通过一个特殊的对象完成:ServiceHost。在上面的例子中,基于WCF服务的类型(typeof(CalculatorService))创建了ServieHost对象,并添加了一个终结点。具体的地址为http://127.0.0.1:9999/calculatorservice,采用了WSHttpBinding,并指定了服务契约的类型ICalculator。

松耦合是SOA的一个基本的特征,WCF应用中客户端和服务端的松耦合体现在客户端只须要了解WCF服务基本的描述,而无须知道具体的实现细节,就可以实现正常的服务调用。WCF服务的描述通过元数据(Metadata)的形式发布出来。WCF中元数据的发布通过一个特殊的服务行为ServiceMetadataBehavior实现。在上面提供的服务寄宿代码中,我们为创建的ServiceHost添加了ServiceMetadataBehavior,并采用了基于HTTP-GET的元数据获取方式,元数据的发布地址通过ServiceMetadataBehavior的HttpGetUrl指定。在调用ServiceHost的Open方法对服务成功寄宿后,我们可以通过该地址获取服务相关的元数据。在IE地址栏上键入http://127.0.0.1:9999/calculatorservice/metadata,你将会得到以WSDL形式体现的服务元数据,如图4所示。

图4 通过HTTP-GET的方式获取WCF服务的元数据

在进行真正的WCF应用开发时,一般不会直接通过编码的方式进行终结点的添加和服务行为的定义,而是通过配置的方式进行。上面添加终结点和定义服务行为的代码可以用下面的配置代替:

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <configuration>
   3:     <system.serviceModel>
   4:         <behaviors>
   5:             <serviceBehaviors>
   6:                 <behavior name="metadataBehavior">
   7:                     <serviceMetadata httpGetEnabled="true" httpGetUrl="http://127.0.0.1:9999/calculatorservice/metadata" />
   8:                 </behavior>
   9:             </serviceBehaviors>
  10:         </behaviors>
  11:         <services>
  12:             <service behaviorConfiguration="metadataBehavior" name="Artech.WcfServices.Services.CalculatorService">
  13:                 <endpoint address="http://127.0.0.1:9999/calculatorservice" binding="wsHttpBinding"                    contract="Artech.WcfServices.Contracts.ICalculator" />
  14:             </service>
  15:         </services>
  16:     </system.serviceModel>
  17: </configuration>

对于初学者来说,WCF的配置显得过于复杂,直接对配置文件进行手工编辑不太现实。在这种情况下,可以直接使用VS提供的配置工具。你可以通过VS的工具(Tools)菜单,选择“WCF Service Configuration Editor”子项,开启这样的一个配置编辑器,如图5所示。

如果采用了上诉的配置,服务寄宿代码将会得到极大的精简,只需包含下面几行代码:

   1: namespace Artech.WcfServices.Hosting
   2: {
   3:     class Program
   4:     {
   5:         static void Main(string[] args)
   6:         {
   7:             using (ServiceHost host = new ServiceHost(typeof(CalculatorService)))
   8:             {                
   9:                 host.Opened += delegate
  10:                 {
  11:                     Console.WriteLine("CalculaorService已经启动,按任意键终止服务!");
  12:                 };
  13:  
  14:                 host.Open();
  15:                 Console.Read();
  16:             }
  17:         }
  18:     }
  19: }

图5 如何获得WCF服务配置编辑器

步骤五:创建客户端调用服务

服务被成功寄宿后,服务端便开始了服务调用请求的监听工作。此外,服务寄宿将服务描述通过元数据的形式发布出来,相应的客户端就可以获取这些元数据创建客户端程序进行服务的消费。在VS下,当我们添加服务引用的时候,VS在内部帮我们实现元数据的获取,并借助这些元数据通过代码生成工具(SvcUtil.exe)自动生成用于服务调用的服务代理相关的代码和相应的配置。

在运行服务寄宿程序(Hosting.exe)的情况下,右键点击Client项目,在弹出的上下文菜单中选择“添加服务引用(Add Service References)”,如图6所示的添加服务引用的对话会显示出来。在地址栏上键入服务元数据发布的源地址:http://127.0.0.1:9999/calculatorservice/metadata,并指定一个命名空间,点击OK按钮,VS为为你生成一系列用于服务调用的代码和配置。

图6 添加服务引用

在一系列自动生成的类中,包含一个服务契约接口、一个服务代理对象和其他相关的类。被客户端直接用于服务调用的是一个继承自ClientBase<CalculatorService>并实现了CalculatorService接口(CalculatorService为客户端生成的服务契约接口类型)的服务代理类。ClientBase<CalculatorService>的定义如下所示:

   1: namespace Artech.WcfServices.Client.CalculatorServices 
   2: {    
   3:     //其他类型成员
   4:     [System.Diagnostics.DebuggerStepThroughAttribute()]
   5:     [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
   6:     public partial class CalculatorServiceClient : System.ServiceModel.ClientBase<Artech.WcfServices.Client.CalculatorServices.CalculatorService>, Artech.WcfServices.Client.CalculatorServices.CalculatorService {
   7:         
   8:         public CalculatorServiceClient() {
   9:         }
  10:         
  11:         public CalculatorServiceClient(string endpointConfigurationName) : 
  12:                 base(endpointConfigurationName) {
  13:         }
  14:         
  15:         public CalculatorServiceClient(string endpointConfigurationName, string remoteAddress) : 
  16:                 base(endpointConfigurationName, remoteAddress) {
  17:         }
  18:         
  19:         public CalculatorServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : 
  20:                 base(endpointConfigurationName, remoteAddress) {
  21:         }
  22:         
  23:         public CalculatorServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : 
  24:                 base(binding, remoteAddress) {
  25:         }
  26:         
  27:         public double Add(double x, double y) {
  28:             return base.Channel.Add(x, y);
  29:         }
  30:         
  31:         public double Subtract(double x, double y) {
  32:             return base.Channel.Subtract(x, y);
  33:         }
  34:         
  35:         public double Multiply(double x, double y) {
  36:             return base.Channel.Multiply(x, y);
  37:         }
  38:         
  39:         public double Divide(double x, double y) {
  40:             return base.Channel.Divide(x, y);
  41:         }
  42: }

我们可以创建CalculatorServiceClient对象,执行相应方法调用服务操作。客户端进行服务调用的代码如下:

   1: using System;
   2: using Artech.WcfServices.Client.CalculatorServices;
   3: namespace Artech.WcfServices.Client
   4: {
   5:     class Program
   6:     {
   7:         static void Main(string[] args)
   8:         {
   9:             using (CalculatorServiceClient proxy = new CalculatorServiceClient())
  10:             {
  11:                 Console.WriteLine("x + y = {2} when x = {0} and y = {1}", 1, 2, proxy.Add(1, 2));
  12:                 Console.WriteLine("x - y = {2} when x = {0} and y = {1}", 1, 2, proxy.Subtract(1, 2));
  13:                 Console.WriteLine("x * y = {2} when x = {0} and y = {1}", 1, 2, proxy.Multiply(1, 2));
  14:                 Console.WriteLine("x / y = {2} when x = {0} and y = {1}", 1, 2, proxy.Divide(1, 2));
  15:             }
  16:         }
  17:     }
  18: }

运行后输出:

x + y = 3 when x = 1 and y = 2
x - y = -1 when x = 1 and y = 2
x * y = 2 when x = 1 and y = 2
x / y = 0.5 when x = 1 and y = 2

客户端通过服务代理对象进行服务的调用,上面的例子通过创建自动生成的、继承自ClientBase<T>的类型对象进行服务调用。实际上,我们还具有另外一种创建服务代理的方法,就是通过ChannelFactory<T>。此外,WCF采用基于契约的服务调用方法,从上面的例子我们也可以看到,VS在进行服务引用添加的过程中,会在客户端创建一个与服务端等效的服务契约接口。在我们的例子中,由于服务端和客户端都是在同一个解决方案中,完全可以让服务端和客户端引用相同的契约。

为了演示这种场景,我们将添加的服务引用移除,并为Client项目添加对Contracts项目的引用。借助于这个服务契约,并通过ChannelFactory<ICalculator>创建服务代理对象,直接进行相应的服务调用。下面的代码演示了基于ChannelFacotory<T>进行服务代理的创建和服务调用的方式。

   1: using System;
   2: using System.ServiceModel;
   3: using Artech.WcfServices.Contracts;
   4: namespace Artech.WcfServices.Client
   5: {
   6:     class Program
   7:     {
   8:         static void Main(string[] args)
   9:         {
  10:             using (ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>(new WSHttpBinding(), "http://127.0.0.1:9999/calculatorservice"))
  11:             {
  12:                 ICalculator proxy = channelFactory.CreateChannel();
  13:                 using (proxy as IDisposable)
  14:                 {
  15:                     Console.WriteLine("x + y = {2} when x = {0} and y = {1}", 1, 2, proxy.Add(1, 2));
  16:                     Console.WriteLine("x - y = {2} when x = {0} and y = {1}", 1, 2, proxy.Subtract(1, 2));
  17:                     Console.WriteLine("x * y = {2} when x = {0} and y = {1}", 1, 2, proxy.Multiply(1, 2));
  18:                     Console.WriteLine("x / y = {2} when x = {0} and y = {1}", 1, 2, proxy.Divide(1, 2));
  19:                 }
  20:             }
  21:         }
  22:     }
  23: }

由于终结点是WCF进行通信的唯一手段,ChannelFactory<T>本质上是通过指定的终结点创建用于进行服务调用的服务代理。在上面的代码中,在创建ChannelFactory<T>的时候再在构造函数中指定终结点的相关要素(契约通过范型类型表示,地址和绑定则通过参数指定)。在真正的WCF应用中,大都采用配置的方式进行终结点的定义。我们可以通过下面的配置指定终结点的三要素,并为相应的终结点指定一个终结点配置名称(calculatorservice)。

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <configuration>
   3:     <system.serviceModel>
   4:         <client>
   5:             <endpoint address="http://127.0.0.1:9999/calculatorservice" binding="wsHttpBinding" contract="Artech.WcfServices.Contracts.ICalculator" name="calculatorservice" />
   6:         </client>
   7:     </system.serviceModel>
   8: </configuration>

那么在创建ChannelFactory<T>的时候,就无须再指定终结点的绑定和地址了,而只须制定对应的终结点配置名称。

   1: using System;
   2: using System.ServiceModel;
   3: using Artech.WcfServices.Contracts;
   4: namespace Artech.WcfServices.Client
   5: {
   6:     class Program
   7:     {
   8:         static void Main(string[] args)
   9:         {
  10:             using (ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>( "calculatorservice"))
  11:             {
  12:             //省略代码
  13:             }
  14:         }
  15:     }
  16: }

步骤六:通过IIS寄宿服务

上面演示了通过自我寄宿的方式寄宿服务,现在我们来演示如何将WCF服务寄宿到IIS中。寄宿IIS的服务寄宿比较简单,基本上包含两个步骤:为WCF服务创建.svc文件和创建IIS虚拟目录。

1、为WCF服务创建.svc文件

我们知道,每一个ASP.NET Web服务都具有一个.asmx文本文件,客户端通过访问.asmx文件实现对相应Web服务的调用。与之类似,每个WCF服务也具有一个对应的文本文件,其文件扩展名为.svc。基于IIS的服务寄宿要求相应的WCF服务具有相应的.svc文件,.svc文件部署于IIS站点中,对WCF服务的调用体现在对.svc文件的访问上。

.svc文件的内容很简单,仅仅包含一个ServiceHost指令(Directive),该指令具有一个必须的Service属性和一些可选的属性。所以最简单的.svc仅仅具有一个包含Service属性(该属性指明了相应的WCF服务的有效类型)的ServiceHost指令。CalculatorService对应的.svc如下所示,我们把该.svc放在Services项目的根目录下,并将文件命名为CalculatorService.svc。

   1: <%@ServiceHost Service="Artech.WcfServices.Services.CalculatorService"%>

2、为WCF服务创建虚拟目录

和一般的寄宿于IIS下的Web应用一样,需要在IIS下创建相应的虚拟目录。在本应用中,为了方便,我们直接把Services项目的根目录映射为IIS虚拟目录,并把该虚拟目录的命名为WcfServices。

接下来需要为通过IIS寄宿的CalculatorService创建配置文件,我们只须在Services的根目录下创建一个Web.config,将WCF相应的配置添加到该配置文件中即可。Web.config所有配置内容如下所示,可以看出,这基本上和上面通过自我寄宿方式定义的配置一致。唯一不同的是在添加的终结点中无须指定地址,因为.svc所在的地址就是服务的地址。也就是说,CalculatorService的地址为http://127.0.0.1/wcfservices/calculatorservice.svc。你可以通过http://127.0.0.1/wcfservices/calculatorservice.svc?wsdl得到相应的元数据。由于WSHttpBinding在默认情况下采用Windows认证,所以在IIS中将Windows集成认证开启。

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <configuration>
   3:     <system.serviceModel>
   4:         <behaviors>
   5:             <serviceBehaviors>
   6:                 <behavior name="metadataBehavior">
   7:                     <serviceMetadata httpGetEnabled="true"/>
   8:                 </behavior>
   9:             </serviceBehaviors>
  10:         </behaviors>
  11:         <services>
  12:             <service behaviorConfiguration="metadataBehavior" name="Artech.WcfServices.Services.CalculatorService">
  13:                 <endpoint  binding="wsHttpBinding" contract="Artech.WcfServices.Contracts.ICalculator" />
  14:             </service>
  15:         </services>
  16: </system.serviceModel>
  17: </configuration>

由于在创建Services项目的时候,我们并不曾引用System.ServiceMode程序集,所以须要加上这样一个引用。此外,一个Web应用在运行的时候会默认从位于根目录下的Bin目录加载程序集,而默认的情况下,我们编译后的程序集会自动保存到Bin\Debug|Release目录下,所以须要通过VS修改Services项目属性,将编译输出目录设置成Bin。

客户端仅仅须要修改终结点的地址,从而转向对寄宿于IIS下的CalculatorService的访问,该地址即为.svc文件的网络地址:http://127.0.0.1/wcfservices/calculatorservice.svc

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <configuration>
   3:     <system.serviceModel>
   4:         <client>
   5:             <endpoint address="http://127.0.0.1/wcfservices/calculatorservice.svc" binding="wsHttpBinding" contract="Artech.WcfServices.Contracts.ICalculator" name="calculatorservice" />
   6:         </client>
   7:     </system.serviceModel>
   8: </configuration>
作者:Artech
出处:http://artech.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
posted @ 2007-02-26 11:13 Artech 阅读(184739) 评论(475) 编辑 收藏

评论共5页: 上一页 1 2 3 4 5 
 回复 引用 查看   
#368楼[楼主] 2011-04-07 10:07 Artech      
引用奎奎:
@Artech
我在使用IIS寄宿服务的时候,调用服务方法时出现了错误。错误信息如下:
“远程服务器返回了意外响应: (405) Method Not Allowed。”
还请楼主不吝赐教。非常感谢!

单单看了这个宽泛的Error Message,很难准确定位出具体哪里的问题。

 回复 引用 查看   
#369楼 2011-04-07 15:37 奎奎      
引用Artech:
引用奎奎:
@Artech
我在使用IIS寄宿服务的时候,调用服务方法时出现了错误。错误信息如下:
“远程服务器返回了意外响应: (405) Method Not Allowed。”
还请楼主不吝赐教。非常感谢!

单单看了这个宽泛的Error Message,很难准确定位出具体哪里的问题。

我也被这个错误给弄糊涂了,我使用的是IIS7。在寄宿的时候IE中查看元数据是可以出来的,就是客户端调用服务的addd方法的时候就报了这个错。实在是头痛啊,刚开始学习WCF对出现的错误不知道从哪里入手排除故障。干了这么久编程都没有遇到过这个错误呢!

 回复 引用 查看   
#370楼 2011-04-07 23:09 奎奎      
问题终于解决了,我把dll、svc和web.config文件拷贝出来放到单独的文件夹里面进行IIS寄宿就可以了。上面我直接把服务实现项目映射为虚拟目录就不行,拷贝上面的文件出来就OK了也不知道是什么原因。
 回复 引用   
#371楼 2011-04-08 16:02 碎心逝梦[未注册用户]
伙在使用IIS寄宿服务的时候,通过客户端控制台程序调用胡时候出现如下错误
System.ServiceModel.CommunicationObjectFaultedException was unhandled
Message="The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state."
Source="mscorlib"
StackTrace:
Server stack trace:
於 System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout)
Exception rethrown at [0]:
於 System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
於 System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
於 System.ServiceModel.ICommunicationObject.Close(TimeSpan timeout)
於 System.ServiceModel.ClientBase`1.System.ServiceModel.ICommunicationObject.Close(TimeSpan timeout)
於 System.ServiceModel.ClientBase`1.Close()
於 ClientForWCFByIIS.Program.Main(String[] args) 於 D:\MyWorkFiles\Myporject\MyStudy\ClientForWCFByIIS\Program.cs: 行 33
於 System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
於 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
於 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
於 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
於 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
於 System.Threading.ThreadHelper.ThreadStart()
InnerException:
请问这个缺失的引用该怎么添加?

 回复 引用 查看   
#372楼 2011-04-12 11:52 ysb2010      
关于你的文章 《我的WCF之旅(1):创建一个简单的WCF程序 》中我有一些问题要请教。

WCF服务配置编辑器这个里面怎么配置的,在你的文章中没有说明。

还有,我是完全按照你的代码来学习WCF做一个测试程序的。请问:

“在进行真正的WCF应用开发时,一般不会直接通过编码的方式进行终结点的添加和服务行为的定义,而是通过配置的方式进行。上面添加终结点和定义服务行为的代码可以用下面的配置代替:”

之后的配置代码是不是在系统生成的app.config中的,我按照你的配置代码在我的配置代码中相应位置粘贴了,之后精简了代码后运行hosting.exe时还是发生了 未定义错误

如果不精简代码(是按照你的精简代码删掉一部分的)。就没有问题,请问是怎么回事。请教如何解决。

你没有回我的段消息,只好在此冒昧了。

 回复 引用 查看   
#373楼[楼主] 2011-04-12 12:25 Artech      
引用ysb2010:
关于你的文章 《我的WCF之旅(1):创建一个简单的WCF程序 》中我有一些问题要请教。

WCF服务配置编辑器这个里面怎么配置的,在你的文章中没有说明。

还有,我是完全按照你的代码来学习WCF做一个测试程序的。请问:

“在进行真正的WCF应用开发时,一般不会直接通过编码的方式进行终结点的添加和服务行为的定义,而是通过配置的方式进行。上面添加终结点和定义服务行为的代码可以用下面的配置代替:”

之后的配置代码是不是在系统生成的app.config中的,我按照你的配置代码在我的配置代码中相应位置粘贴了,之后精简了代码后运行hosting.exe时还是发生了 未定义错...

1. 通过菜单Tools-〉WCF Service Configuration Editor开启WCF服务配置编辑器;
2. 想知道你真正的代码、配置和异常

 回复 引用 查看   
#374楼 2011-04-12 12:52 ysb2010      
看了前面的回复,我明白了。好像APP.config不止1个。我在系统里自动生成的只有在client下有一个。
 回复 引用 查看   
#375楼 2011-04-12 15:12 立華奏      
iis寄宿用的.svc文件怎么添加啊
 回复 引用 查看   
#376楼[楼主] 2011-04-12 15:18 Artech      
引用立華奏:iis寄宿用的.svc文件怎么添加啊

我一般添加一个Text文件,将后缀名改成svc

 回复 引用 查看   
#377楼 2011-04-12 15:22 立華奏      
@Artech
O(∩_∩)O谢谢

 回复 引用 查看   
#378楼 2011-04-12 15:22 立華奏      
@Artech
我还以为缺少模板什么的呢

 回复 引用 查看   
#379楼 2011-04-13 19:02 凌寒飘香      
多谢楼主给的例子,对我这个初学者很有帮助。有一个问题向你请教。
在Client项目的app.config中,加入了
<endpoint address="http://127.0.0.1:9999/calculatorservice" binding="wsHttpBinding"...
运行Hosting.exe,Program.cs能计算出正确的结果。

但当address=http://127.0.0.1:8000/calculatorservice.svc时
关闭Hosting.exe所运行的窗口,也就是关闭服务。
为什么还能运行成功,
Client.CalculatorService,所配置的服务地址已经打不开了,为什么proxy还能调用add等方法呢?
想不明白,请指点,拜谢!

Client项目的Program.cs代码如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Contracts;
using Client.CalculatorService;

namespace Client
{
class Program
{
static void Main(string[] args)
{
using (CalculatorServiceClient proxy = new CalculatorServiceClient())
{
Console.WriteLine("x + y = {2} when x = {0} and y = {1}", 1, 2, proxy.Add(1, 2));
Console.WriteLine("x - y = {2} when x = {0} and y = {1}", 1, 2, proxy.Subtract(1, 2));
Console.WriteLine("x * y = {2} when x = {0} and y = {1}", 1, 2, proxy.Multiply(1, 2));
Console.WriteLine("x / y = {2} when x = {0} and y = {1}", 1, 2, proxy.Divide(1, 2));
}
}
}
}

 回复 引用 查看   
#380楼[楼主] 2011-04-13 19:36 Artech      
引用凌寒飘香:
多谢楼主给的例子,对我这个初学者很有帮助。有一个问题向你请教。
在Client项目的app.config中,加入了
<endpoint address="http://127.0.0.1:9999/calculatorservice" binding="wsHttpBinding"...
运行Hosting.exe,Program.cs能计算出正确的结果。

但当address=http://127.0.0.1:8000/calculatorservice.svc时
关闭Hosting.exe所运行的窗口,也就是关闭服务。
为什么还能运行成功,
Client.Calculator...

访问的是两个不同的服务嘛!

 回复 引用 查看   
#381楼 2011-04-13 19:56 凌寒飘香      
引用Artech:
引用凌寒飘香:
多谢楼主给的例子,对我这个初学者很有帮助。有一个问题向你请教。
在Client项目的app.config中,加入了
<endpoint address="http://127.0.0.1:9999/calculatorservice" binding="wsHttpBinding"...
运行Hosting.exe,Program.cs能计算出正确的结果。

但当address=http://127.0.0.1:8000/calculatorservice.svc时
关闭Hosting.exe所运行的窗口,也就是关闭服务。
为什么还能运行成功,
Cl...

是不是Client.CalculatorService以address所指定的服务地址为准。和建Web引用(CalculatorService)时指定的地址没什么关系。
 回复 引用 查看   
#382楼[楼主] 2011-04-13 22:32 Artech      
引用凌寒飘香:
引用Artech:
引用凌寒飘香:
多谢楼主给的例子,对我这个初学者很有帮助。有一个问题向你请教。
在Client项目的app.config中,加入了
<endpoint address="http://127.0.0.1:9999/calculatorservice" binding="wsHttpBinding"...
运行Hosting.exe,Program.cs能计算出正确的结果。
但当address=http://127.0.0.1:8000/calculatorservice.svc时
关闭Hosting.exe所运行的窗口,也就是关闭服务。
...

使用到的Endpoint的地址决定调用的服务...

 回复 引用 查看   
#383楼 2011-04-15 13:58 Brad Xue      
引用刘全成:
大哥,你好:我练习了这篇文章的2、3、4步。可是提示“ServiceMetadataBehavior 的 HttpGetEnabled 属性设置为 True,而 HttpGetUrl 属性是相对地址,但没有 http 基址。请提供 http 基址或将 HttpGetUrl 设置为绝对地址。”。
你可以帮我指点一下吗?
代码如下:
1.

[ServiceContract(Name="CalculatorService", Namespace="http://www.artech.com/")]
public interface ICalculator
{ ...



我试了一把报同样的错误,楼主给解决一下吧!

 回复 引用 查看   
#384楼 2011-04-15 16:57 齐颂      
通信对象 System.ServiceModel.ServiceHost 无法用于通信,因为其处于“出错”状态。
 回复 引用 查看   
#385楼 2011-04-19 16:06 小齐宝      
"在一系列自动生成的类中,包含一个服务契约接口、一个服务代理对象和其他相关的类。 "
为什么我什么也没有生成?
除了Service References 下面多了一个app.config
是因为我的工程文件不对吗?我创建的是一个Console项目

 回复 引用 查看   
#386楼[楼主] 2011-04-19 21:18 Artech      
引用小齐宝:
"在一系列自动生成的类中,包含一个服务契约接口、一个服务代理对象和其他相关的类。 "
为什么我什么也没有生成?
除了Service References 下面多了一个app.config
是因为我的工程文件不对吗?我创建的是一个Console项目

你点开开Service Reference包含的文件看看...

 回复 引用 查看   
#387楼 2011-04-20 14:33 小齐宝      
@Artech
Service References 下面只有一个 CalculatorServies。

 回复 引用 查看   
#388楼 2011-04-20 14:33 小齐宝      
@Artech
Service References 下面只有一个 CalculatorServies。

 回复 引用 查看   
#389楼 2011-04-20 16:33 涂to途      
不知道该说什么 你的代码 是否可以运行
 回复 引用 查看   
#390楼[楼主] 2011-04-20 16:58 Artech      
引用小齐宝:
@Artech
Service References 下面只有一个 CalculatorServies。

既然你成功添加了Service Reference,那么在这个Reference附加文件中就会有相关.cs,

 回复 引用 查看   
#391楼 2011-04-23 21:02 linyugeng      
好详细的文章,适合我这种初学者,学习了
 回复 引用 查看   
#392楼 2011-04-25 21:48 xwdreamer      
@kevin0227
请问是哪里的终结点地址不对啊。我也遇到同样的错误了,调试很久没弄明白。

 回复 引用 查看   
#393楼 2011-05-18 17:20 静心涤虑      
请教楼主与诸位高手:
我操作到 “步骤六:通过IIS寄宿服务”,输入http://127.0.0.1/wcfservices/calculatorservice.svc?wsdl怎么得不到相应的元数据" target="_blank">http://127.0.0.1/wcfservices/calculatorservice.svc?wsdl怎么得不到相应的元数据!显示:找不到类型“WcfServices.Services.CalculatorService”,它在 ServiceHost 指令中提供为 Service 特性值,或在配置元素 system.serviceModel/serviceHostingEnvironment/serviceActivations 中提供。


CalculatorService.svc 与 iis虚拟目录 WebConfig 都按着步骤创建的!

在地址栏输入:http://127.0.0.1/wcfservices/calculatorservice.svc 也显示 找不到类型“WcfServices.Services.CalculatorService”,它在 ServiceHost 指令中提供为 Service 特性值,或在配置元素 system.serviceModel/serviceHostingEnvironment/serviceActivations 中提供。

我现在是不知道哪错了?应该怎么做呢?步骤6之前都能正常显示!

谢谢!







 回复 引用   
#394楼 2011-06-03 11:39 樱篱[未注册用户]
跑通,一切正常,多谢。
 回复 引用 查看   
#395楼 2011-06-06 16:13 guddujianxiao      
楼主你好:
看了你的例子,在步骤五 中
  
 using (ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>(new WSHttpBinding(), "http://127.0.0.1:9999/calculatorservice")) { 
ICalculator proxy = channelFactory.CreateChannel(); 
  using (proxy as IDisposable){  
 Console.WriteLine("x + y = {2} when x = {0} and y = {1}", 1, 2, proxy.Add(1, 2));  
Console.WriteLine("x - y = {2} when x = {0} and y = {1}", 1, 2, proxy.Subtract(1, 2));  
 Console.WriteLine("x * y = {2} when x = {0} and y = {1}", 1, 2, proxy.Multiply(1, 2));  
 Console.WriteLine("x / y = {2} when x = {0} and y = {1}", 1, 2, proxy.Divide(1, 2));  
        }  
 }

抛出 如下异常
Secure channel cannot be opened because security negotiation with the remote endpoint has failed. This may be due to absent or incorrectly specified EndpointIdentity in the EndpointAddress used to create the channel. Please verify the EndpointIdentity specified or implied by the EndpointAddress correctly identifies the remote endpoint.
上网搜索也没有解决。请楼主帮忙解决一下。谢谢

 回复 引用 查看   
#396楼 2011-06-06 16:15 guddujianxiao      
不好意思,代码排版很丑
 回复 引用 查看   
#397楼 2011-06-06 16:30 guddujianxiao      
还有第六步。
我在Services中 add .svc 时 ,怎么没有找到 以 .svc 后缀名 的文件呢。
我用的是 vs2010

 回复 引用 查看   
#398楼 2011-06-06 18:29 guddujianxiao      
呵呵~,关于刚才我在395楼提出问题已解决。原因在于
宿主项目中
host.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(SecurityMode.None), "http://127.0.0.1:9999/calculatorservice"); 多添加一个SecurityMode.None 枚举,把它去掉就可以通过了。
具体原因不知道怎么解释。还希望楼主给与正确的解释。谢谢

 回复 引用 查看   
#399楼 2011-06-07 14:04 jiang_chao      
楼主你好!看了楼上很多兄弟都在第六步有问题,我的也是,能不能在讲详细一点点!谢谢!无法找到 ServiceHost 指令中作为服务属性值提供的类型“Services.CalculatorService”。]
 回复 引用 查看   
#400楼[楼主] 2011-06-07 21:13 Artech      
引用guddujianxiao:
还有第六步。
我在Services中 add .svc 时 ,怎么没有找到 以 .svc 后缀名 的文件呢。
我用的是 vs2010

在Add New Item模板中没有专门的.svc,不过这仅仅是个文本文件而已,添加一个Text文件,扩展名改成.svc即可。

 回复 引用 查看   
#401楼[楼主] 2011-06-07 21:13 Artech      
引用guddujianxiao:
呵呵~,关于刚才我在395楼提出问题已解决。原因在于
宿主项目中
host.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(SecurityMode.None), "http://127.0.0.1:9999/calculatorservice"); 多添加一个SecurityMode.None 枚举,把它去掉就可以通过了。
具体原因不知道怎么解释。还希望楼主给与正确的解释。谢谢

好像在我的文章中没有使用None安区模式。

 回复 引用 查看   
#402楼[楼主] 2011-06-07 21:19 Artech      
引用jiang_chao:楼主你好!看了楼上很多兄弟都在第六步有问题,我的也是,能不能在讲详细一点点!谢谢!无法找到 ServiceHost 指令中作为服务属性值提供的类型“Services.CalculatorService”。]

其实我个人觉得我实在没有办法再详细了,这个过程很简单。
1、将Service Project所在的目录影射为IIS虚拟目录,并开启Windows集成认证;
2、将编译目录从/bin/debug改称bin;
3、添加.svc文件
4、添加web.config并添加配置
服务端寄宿结束
客户端将地址改称.svc的地址即可


 回复 引用 查看   
#403楼 2011-06-08 11:10 Sunyf      
”不包含适合于入口点的静态“Main”方法“
我做的总是提示这个,客户端也运行不了,服务端可以运行,这个是什么原因啊?

 回复 引用 查看   
#404楼[楼主] 2011-06-08 12:17 Artech      
引用Sunyf:
”不包含适合于入口点的静态“Main”方法“
我做的总是提示这个,客户端也运行不了,服务端可以运行,这个是什么原因啊?

这不很明显?不包含适合于入口点的静态“Main”方法!

 回复 引用 查看   
#405楼 2011-06-08 15:31 ysb2010      
@Artech


谢谢博主不辞辛苦的回答,CalculatorService.svc已在IIS端调试成功。

但是奇怪的一点是如果加上wcfservices目录就会出现

“/”应用程序中的服务器错误。
--------------------------------------------------------------------------------

无法找到资源。
说明: HTTP 404。您正在查找的资源(或者它的一个依赖项)可能已被移除,或其名称已更改,或暂时不可用。请检查以下 URL 并确保其拼写正确。

请问是什么原因?谢谢

 回复 引用 查看   
#406楼 2011-06-08 15:53 ysb2010      
我的iis的默认站点改名为wcfservices,虚拟目录为Services,
应用程序名:Artech.WcfServices.Services.CalculatorService。请问哪里还有问题?

另外,svcutil.exe这个文件我搜遍了整个硬盘也找不到。

 回复 引用 查看   
#407楼 2011-06-11 16:27 guddujianxiao      
呵呵!今天有空又来看Artech老师 的文章了.
 回复 引用 查看   
#408楼 2011-06-11 16:48 guddujianxiao      
买了WCF卷一这本书 ,刚好这周遇到用WCF序列化类。要求序列化成XML时,不许要命名空间、节点要排序以及数据成员的值 等于默认值的情况下,就不要将其序列化到xml中。就在纠结中 ,在文章的5.2 当中都给出了答案。让我饮刃而解 。非常感谢哦,继续关注你的文章 。
顺便附上解决思路:
1.序列化XML时不许要命名空间,则在类上用[DataContract(Namespace="")]
2.节点排序,在字段或属性上用DataMember 的Order 属性
3.数据成员的值 等于默认值的情况下,就不要将其序列化到xml中在字段或属性上用DataMember 的EmitDefaultValue 属性

 回复 引用 查看   
#409楼 2011-06-22 12:02 Quentin lee      
07年的文章,现在才看到,惭愧……
不知道现在学习晚不晚?

 回复 引用 查看   
#411楼 2011-07-04 01:48 henny      
引用Artech:
引用jiang_chao:楼主你好!看了楼上很多兄弟都在第六步有问题,我的也是,能不能在讲详细一点点!谢谢!无法找到 ServiceHost 指令中作为服务属性值提供的类型“Services.CalculatorService”。]

其实我个人觉得我实在没有办法再详细了,这个过程很简单。
1、将Service Project所在的目录影射为IIS虚拟目录,并开启Windows集成认证;
2、将编译目录从/bin/debug改称bin;
3、添加.svc文件
4、添加web.config并添加配置
服务端寄宿结束
客户端将地址改称.svc的地址即可


遇见同样的问题,我将目标框架4.0改成3.5以后能正常实现IIS寄宿服务。
运行Client之前最好重新引用一次服务。我的服务地址是http://localhost/WcfServices/Service.svc;这个根据个人创建来引用。引用后正常得出结果。
希望对跟我有同样问的有帮助。至于为啥4.0改成3.5运行正常还不太明白,有可能4.0的版本问题,我是连带VS2010一起安装的。如果有朋友知道原因,请说一声哈

 回复 引用 查看   
#412楼 2011-07-19 17:46 青山依旧在      
好文章,顶!
 回复 引用 查看   
#413楼 2011-07-25 15:50 jsenke      
请问,第四步骤中的http://127.0.0.1:9999/calculatorservice/metadata 地址是怎么来的?要在iis中做什么配置吗?
 回复 引用 查看   
#414楼 2011-07-28 09:34 MSYXing      
请问下楼主,我把Host中的Console.Read()放在Using()外面,运行后http://127.0.0.1:9999/calculatorservice/metadata就找不到了,没有异常,Host也正常Open了,后来放回Using()里面有正确了,请问是什么问题?
 回复 引用 查看   
#415楼[楼主] 2011-07-28 10:23 Artech      
引用MSYXing:请问下楼主,我把Host中的Console.Read()放在Using()外面,运行后http://127.0.0.1:9999/calculatorservice/metadata就找不到了,没有异常,Host也正常Open了,后来放回Using()里面有正确了,请问是什么问题?

Console.Read()阻止ServiceHost被Dispose。

 回复 引用 查看   
#416楼 2011-07-28 21:49 落魂涧      
lz有些代码截图不是很清晰,有没有电子版的!
支持lz

 回复 引用 查看   
#417楼 2011-08-02 21:12 name_456      
楼主你好:我第六步出问题 不晓得怎么回事:

无法显示 XML 页。
使用 XSL 样式表无法查看 XML 输入。请更正错误然后单击 刷新按钮,或以后重试。


--------------------------------------------------------------------------------

名称以无效字符开头。处理资源 'file:///C:/Documents and Settings/Administrator/桌面/SolutionWcfServices/Artech.WcfServices.Services/Calcula...

<%@ServiceHost Service="Artech.WcfServices.Services.CalculatorService"%>
-^

 回复 引用 查看   
#418楼 2011-08-04 14:13 傻马难骑      
很详细,不过第六步寄宿到IIS一直提示配置出错(有零个应用程序(非基础结构)终结点),改了一天,检查,重写无数遍没发现问题(痛苦),今天终于发现问题,在添加配置文件时,因为项目是类库,默认添加的配置文件名是App.config,需要改为Web.config,貌似II不认识APP配置文件,希望对和我犯同样错误的朋友有帮助
 回复 引用 查看   
#419楼 2011-08-05 15:57 fish_1949      
实际上,我们还具有另外一种创建服务代理的方法,就是通过ChannelFactory<T>。此外,WCF采用基于契约的服务调用方法,从上面的例子我们也可以看到,VS在进行服务引用添加的过程中,会在客户端创建一个与服务端等效的服务契约接口。在我们的例子中,由于服务端和客户端都是在同一个解决方案中,完全可以让服务端和客户端引用相同的契约。------------------------------------------------
请问如果不在同一个解决方案,还可以通过ChannelFactory<T>引用吗,这时候接口T怎么办。。。(不好意思,菜鸟问题。。)

 回复 引用 查看   
#420楼 2011-08-19 14:02 云端漫步      
public partial class CalculatorServiceClient : ClientBase<Artech.WcfServices.Client.CalculatorServices.CalculatorService>, Artech.WcfServices.Client.CalculatorServices.CalculatorService

运行报错:错误 1 命名空间“Artech.WcfServices.Client.CalculatorServices”中不存在类型或命名空间名称“CalculatorService”,你能提供代码下载吗

 回复 引用 查看   
#421楼 2011-08-23 22:15 Frankycat      
楼主神人啊。
看了很多入门的教程,都不怎么明白WCF。
只有在这又种豁然开朗的感觉。谢谢楼主分享。

 回复 引用 查看   
#422楼 2011-09-05 16:58 lzz2882      
十分好,极力推荐!
 回复 引用 查看   
#423楼 2011-09-09 11:14 jy87909      
楼主这文章写的太好了,感谢分享!马上去买书去。
 回复 引用 查看   
#424楼 2011-09-13 17:01 C C      
LZ
 回复 引用 查看   
#425楼 2011-09-20 17:02 小菜卖饭      
老大 我按照你的 说明在iis 配置了 :但是有问题
找不到类型“Vancl.Wcf.Services.CalculatorService”,它在 ServiceHost 指令中提供为 Service 特性值,或在配置元素 system.serviceModel/serviceHostingEnvironment/serviceActivations 中提供。
如果 把虚拟目录 改成 应用程序就没问题了 ,请问 这是什么原因呢 谢谢

 回复 引用 查看   
#426楼[楼主] 2011-09-20 18:37 Artech      
引用小菜卖饭:
老大 我按照你的 说明在iis 配置了 :但是有问题
找不到类型“Vancl.Wcf.Services.CalculatorService”,它在 ServiceHost 指令中提供为 Service 特性值,或在配置元素 system.serviceModel/serviceHostingEnvironment/serviceActivations 中提供。
如果 把虚拟目录 改成 应用程序就没问题了 ,请问 这是什么原因呢 谢谢

对于IIS 7(Or Later)就应该是Web Application,这个的IIS虚拟目录只要使用之前IIS版本的说法。

 回复 引用 查看   
#427楼 2011-09-23 00:19 NigelD7      
文章写得出奇的简单,清晰。好!
 回复 引用   
#428楼 2011-09-23 10:42 台北132[未注册用户]
麻烦大虾,小菜期待你的源代码
 回复 引用 查看   
#429楼 2011-09-23 11:49 丁小贝      
+1
引用Frankycat:
楼主神人啊。
看了很多入门的教程,都不怎么明白WCF。
只有在这又种豁然开朗的感觉。谢谢楼主分享。

 回复 引用 查看   
#430楼 2011-09-23 17:31 北小孩      
您好,我照着做怎么出现:
未处理的“System.ServiceModel.ServiceActivationException”类型的异常出现在 mscorlib.dll 中。

其他信息: 无法激活请求的服务“http://127.0.0.1/wcfservices/calculatorservice.svc”。有关详细信息,请参阅服务器的诊断跟踪日志。

这个错误啊,直接在IIS中打开svc:
出现:
“/WcfServices”应用程序中的服务器错误。

无法找到 ServiceHost 指令中作为服务属性值提供的类型“CalculatorService”。

说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。

异常详细信息: System.InvalidOperationException: 无法找到 ServiceHost 指令中作为服务属性值提供的类型“CalculatorService”。

源错误:

执行当前 Web 请求期间生成了未处理的异常。可以使用下面的异常堆栈跟踪信息确定有关异常原因和发生位置的信息。

堆栈跟踪:


[InvalidOperationException: 无法找到 ServiceHost 指令中作为服务属性值提供的类型“CalculatorService”。]
System.ServiceModel.Activation.ServiceHostFactory.CreateServiceHost(String constructorString, Uri[] baseAddresses) +4077454
System.ServiceModel.HostingManager.CreateService(String normalizedVirtualPath) +11729164
System.ServiceModel.HostingManager.ActivateService(String normalizedVirtualPath) +42
System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath) +479

[ServiceActivationException: 由于编译过程中出现异常,无法激活服务“/WcfServices/CalculatorService.svc”。异常消息为: 无法找到 ServiceHost 指令中作为服务属性值提供的类型“CalculatorService”。。]
System.ServiceModel.AsyncResult.End(IAsyncResult result) +11599786
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult result) +194
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.ExecuteSynchronous(HttpApplication context, Boolean flowContext) +176
System.ServiceModel.Activation.HttpModule.ProcessRequest(Object sender, EventArgs e) +278
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +68
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75

版本信息: Microsoft .NET Framework 版本:2.0.50727.3623; ASP.NET 版本:2.0.50727.3618

帮忙啊

 回复 引用 查看   
#431楼 2011-10-17 17:53 HaiJia Hou      
请教一个问题:
WCF能否叫2个或多个endpoint之间相互通信?
我看到的wcf都是host application与endpoint间的通信,不知道能否让endpoint1与endpoint2相互通信?如果可以,是怎样的通信机制,怎么做到的?谢谢!

 回复 引用 查看   
#432楼 2011-10-18 14:20 ylszjin      
你好,我是新手,以后常来观看,呵呵!
 回复 引用 查看   
#433楼 2011-10-22 19:26 Jason.Li      
@Artech
我开始也在第六步遇到同样的问题,百思不得其解。后来直接建了一个空白页,运行提示说‘无法访问IIS元数据’,查了一下,重新注册了IIS。这个问题就解决了。
大家可试下:
aspnet_regiis -i

 回复 引用 查看   
#434楼 2011-10-22 19:27 Jason.Li      
楼主这个帖子太强了,感谢分享 :)
 回复 引用 查看   
#435楼 2011-10-22 19:32 Jason.Li      
另外,不会用 ‘WCF 服务配置编辑器’的同学可以参考这个帖子,手把手教学啊:
http://blog.csdn.net/canduecho/article/details/5051120

 回复 引用 查看   
#436楼 2011-10-25 16:44 HiFly      
能否把IIS寄宿服务配置IIS讲解详细点呢?我配置IIS时候把WINDOWS集成认证启用,并去掉匿名访问,打开http://127.0.0.1/wcfservices/calculatorservice.svc的时候提示叫我输入用户和密码,不知是怎么回事,因此寄宿到IIS一直没成功,希望博主能详细讲下,谢谢!!!(我是XP)
 回复 引用 查看   
#437楼 2011-11-03 08:47 Kingdom_0      
在运行服务寄宿程序(Hosting.exe)的情况下,右键点击Client项目,在弹出的上下文菜单中选择“添加服务引用(Add Service References)”,

Add Service Reference选项是灰的,选不了,怎么办?

 回复 引用 查看   
#438楼 2011-11-03 13:48 华-子      
学习了,呵呵!
 回复 引用 查看   
#439楼 2011-11-09 10:50 xdxy06      
谢谢楼主哈,提供了自定义host,与寄宿IIS的实例。我是用VS2010开发的,做到最后一个寄宿IIS时,遇到两个问题,一个是需要给在Services项目添加ASPNET权限,否则无法读取;还有一个是将挂载的站点ASPNET的版本设置成4,否则会有编译错误。
 回复 引用 查看   
#440楼 2011-11-09 10:56 幻元素      
一次性测试通过,感谢楼主
 回复 引用 查看   
#441楼 2011-11-10 16:28 山中客      
学习!
 回复 引用 查看   
#442楼 2011-11-11 17:00 猪头san      
和谐的很,完美通过。~感谢
 回复 引用 查看   
#443楼 2011-11-16 15:42 山中客      
在运行服务寄宿程序(Hosting.exe)的情况下,右键点击Client项目,在弹出的上下文菜单中选择“添加服务引用(Add Service References)”,----这个怎么搞啊!!!!
 回复 引用 查看   
#444楼[楼主] 2011-11-18 16:39 Artech      
引用山中客:在运行服务寄宿程序(Hosting.exe)的情况下,右键点击Client项目,在弹出的上下文菜单中选择“添加服务引用(Add Service References)”,----这个怎么搞啊!!!!

直接指定Host.exe不就可以了吗?

 回复 引用   
#445楼 2011-11-19 20:40 2000killer[未注册用户]
IIS 作为宿主的时,出现404,405,403,xml解析错误的原因在于IIS不能解析.svc的后缀请求。解决办法,在虚拟目录中添加svc后缀扩展名的aspnet_isapi.dll解析路径。
至于Windows集成认证开不开启,好像都无所谓。

 回复 引用   
#446楼 2011-11-19 20:46 2000killer[未注册用户]
引用Artech:
引用山中客:在运行服务寄宿程序(Hosting.exe)的情况下,右键点击Client项目,在弹出的上下文菜单中选择“添加服务引用(Add Service References)”,----这个怎么搞啊!!!!

直接指定Host.exe不就可以了吗?


1. 在Host项目的bin目录下运行exe文件。
2. 然后在IDE环境中右键点击Client项目,添加服务引用

 回复 引用 查看   
#447楼 2011-11-20 16:34 刘江北      
很少看到有人的帖子回复率这么高,很钦佩大哥这种职业道德,让小弟们受益匪浅,谢谢。
 回复 引用 查看   
#448楼 2011-11-26 17:32 蔡建良      
源码下载:
http://www.cnblogs.com/janehlp/archive/2011/11/26/2264469.html

测试环境: win7+vs2008+iis7

 回复 引用 查看   
#449楼 2011-12-01 14:16 dongdongc      
你好,我在iis寄宿的时候 用浏览器查看http://127.0.0.1/WCFService/CalculatorService.svc?wsdl 为什么会出现Server Application Unavailable 的错误,好像是权限的问题,不过在网上没有找到合适的答案,还请楼主赐教!谢谢
 回复 引用 查看   
#450楼 2011-12-04 21:01 阿沥      
看错了,把控制台项目作为IIS的虚拟目录,搞了半天,无法找到类型,看了些其它人的问题后,才重新整理后才看清是service项目。
但作为虚拟目录也跑不起来,无法找到类型,但建一新网站后就可以了,环境为windows 7,IIS7.虽然已经成功跑起来了,但还是不明白为什么作为虚拟目录跑不了,但作为网站就能跑了。

 回复 引用 查看   
#451楼 2011-12-06 11:09 一颗空心菜      
我学的太迟了…………
看的满头大汗……

 回复 引用 查看   
#452楼 2011-12-15 16:42 Exception369      
文章简直太好了!
发现一点小小的问题:文章在讲IIS寄宿时,说“由于在创建Services项目的时候,我们并不曾引用System.ServiceMode程序集,所以须要加上这样一个引用。” 需要添加引用吗?由于Services引用了Contracts项目,而Contracts项目引用了System.ServiceMode,所以我感觉应该不需要引用。
不知道我理解的对不,还请大师指正!

 回复 引用 查看   
#453楼 2011-12-18 21:11 yikuyirong      
请问一下,在c#客户端上wcf方法可不可以通过方法名的字符串方式来调用呢。
 回复 引用 查看   
#454楼 2011-12-27 15:45 王秀银      
楼主您好,
请问一下下面这个错应该是没有找到我写的那个配置文件吧,要怎么弄啊,

服务“Services.CalculatorServices”有零个应用程序(非基础结构)终结点。这可能是因为未找到应用程序的配置文件,或者在配置文件中未找到与服务名称匹配的服务元素,或者服务元素中未定义终结点。

 回复 引用 查看   
#455楼 2011-12-30 14:44 王秀银      
“/wcf”应用程序中的服务器错误。
--------------------------------------------------------------------------------
未能加载文件或程序集“Contracts”或它的某一个依赖项。生成此程序集的运行库比当前加载的运行库新,无法加载此程序集。
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。

异常详细信息: System.BadImageFormatException: 未能加载文件或程序集“Contracts”或它的某一个依赖项。生成此程序集的运行库比当前加载的运行库新,无法加载此程序集。
源错误:
执行当前 Web 请求期间生成了未处理的异常。可以使用下面的异常堆栈跟踪信息确定有关异常原因和发生位置的信息。

程序集加载跟踪: 下列信息有助于确定程序集“Contracts”无法加载的原因。

警告: 程序集绑定日志记录被关闭。
要启用程序集绑定失败日志记录,请将注册表值 [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD)设置为 1。
注意: 会有一些与程序集绑定失败日志记录关联的性能损失。
要关闭此功能,请移除注册表值 [HKLM\Software\Microsoft\Fusion!EnableLog]。

堆栈跟踪:
[BadImageFormatException: 未能加载文件或程序集“Contracts”或它的某一个依赖项。生成此程序集的运行库比当前加载的运行库新,无法加载此程序集。]
System.Reflection.Assembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection) +0
System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection) +43
System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) +127
System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) +142
System.Reflection.Assembly.Load(String assemblyString) +28
System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective) +46

[ConfigurationErrorsException: 未能加载文件或程序集“Contracts”或它的某一个依赖项。生成此程序集的运行库比当前加载的运行库新,无法加载此程序集。]
System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective) +613
System.Web.Configuration.CompilationSection.LoadAllAssembliesFromAppDomainBinDirectory() +203
System.Web.Configuration.CompilationSection.LoadAssembly(AssemblyInfo ai) +105
System.Web.Compilation.BuildManager.GetReferencedAssemblies(CompilationSection compConfig) +178
System.Web.Compilation.WebDirectoryBatchCompiler..ctor(VirtualDirectory vdir) +163
System.Web.Compilation.BuildManager.BatchCompileWebDirectoryInternal(VirtualDirectory vdir, Boolean ignoreErrors) +53
System.Web.Compilation.BuildManager.BatchCompileWebDirectory(VirtualDirectory vdir, VirtualPath virtualDir, Boolean ignoreErrors) +175
System.Web.Compilation.BuildManager.CompileWebFile(VirtualPath virtualPath) +83
System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile) +261
System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile) +101
System.Web.Compilation.BuildManager.GetVPathBuildResult(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile) +83
System.Web.Compilation.BuildManager.GetCompiledCustomString(String virtualPath) +27
System.ServiceModel.HostingManager.GetCompiledCustomString(String normalizedVirtualPath) +134
System.ServiceModel.HostingManager.CreateService(String normalizedVirtualPath) +23
System.ServiceModel.HostingManager.ActivateService(String normalizedVirtualPath) +42
System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath) +479

楼主帮帮忙啊 这个是怎么回事啊!

 回复 引用 查看   
#456楼 2011-12-30 15:07 朝阳丶李森      
蒋老师您好,麻烦问下我用Windows服务承载WCF服务,我启动服务的时候给我说“服务启动后自动停止,某些服务在未由其他服务或程序使用时将自动停止”这个改怎么改呢,麻烦老师指点下。
 回复 引用 查看   
#457楼 2012-01-05 10:02 know it,learn lt      
引用王秀银:
“/wcf”应用程序中的服务器错误。
--------------------------------------------------------------------------------
未能加载文件或程序集“Contracts”或它的某一个依赖项。生成此程序集的运行库比当前加载的运行库新,无法加载此程序集。
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。

异常详细信息: System.BadImageFormatException: 未能加载文件或程序集“Contracts”或它的某一...

版本问题吧 程序池 改成 4.0集成

 回复 引用 查看   
#458楼 2012-01-05 17:34 蜗牛也是牛      
受益匪浅,非常感谢!
 回复 引用 查看   
#459楼 2012-01-06 14:41 dandanlife      
lz,您好
我在使用WCF时遇到了一个这样的问题:
Could not find endpoint element with name 'BasicHttpBinding_IIdentityService' and contract 'IdentityService.IIdentityService' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this name could be found in the client element.
不知道您是否也遇到过呢?我在网上找了许久也没找到解决方案。WCF做为我的服务端(asp.net的WCF服务程序),我的客户端是winform程序,这个问题出在程序编译之后。我以client端写了一个用户控件,控件的load事件调用了WCF中的方法,当我将用户控件拖动到新的窗体上时将会出现上面的异常,导致我的用户控件不可用。但是只要将用户控件的load事件中对WCF访求的调用去掉之后,用户控件就可正常显示了。按照异常的提示,服务端也客户端的配置文件都进行了配置,不知道还有哪些地方没有考虑到呢?请LZ指点,谢谢了

 回复 引用 查看   
#460楼 2012-01-06 15:17 Alsmile      
你好,请问

using (CalculatorServiceClient proxy = new CalculatorServiceClient())
{
try
{
Console.WriteLine("x + y = {2} when x = {0} and y = {1}", 1, 2, proxy.Add(1, 2));
Console.WriteLine("x - y = {2} when x = {0} and y = {1}", 1, 2, proxy.Subtract(1, 2));
Console.WriteLine("x * y = {2} when x = {0} and y = {1}", 1, 2, proxy.Multiply(1, 2));
Console.WriteLine("x / y = {2} when x = {0} and y = {1}", 1, 2, proxy.Divide(1, 2));
}
catch (System.Exception ex)
{

}
}
上面粗体代码发生如下异常,怎么回事呢?(刚接触wcf,照着博客做的)
{"目标“http://127.0.0.1:9999/calculatorservice”的“http://127.0.0.1:9999/calculatorservice”与 SOAP 的安全协商失败。有关详细信息,请参见内部异常。"}

 回复 引用   
#461楼 2012-01-29 11:23 若水19[未注册用户]
http://download.csdn.net/detail/pengzhihua/4031356
各位在iis上部署失败的可以参考这篇文章,解决办法好全的啊

 回复 引用 查看   
#462楼 2012-02-01 20:37 wycoo      
按照老师的提示,一切正常。
 回复 引用 查看   
#463楼 2012-02-03 17:20 爱让一切都对了      
跟着做了一遍,一切正常,非常感谢。
 回复 引用 查看   
#464楼 2012-02-07 11:46 小师傅      
弱弱问句
wcf 数据协定与消息协定有什么区别?

 回复 引用 查看   
#465楼 2012-02-09 21:24 星空(StarrySky)      
非常好的文章,但是小弟在IIS寄宿时遇到了问题。Can you help me?

小弟,用的是VS2010和IIS7...
1、
这是项目中文件目录。

2、Debug编译路径设置:

3、Debug后输出


问题一:没有输出“svc”和“web.config”文件,这是为什么?

4、没关系,手动创建:


5、IIS7添加应用程序


6、客户端访问出现错误:
响应消息的内容类型 text/html; charset=utf-8 与绑定(application/soap+xml; charset=utf-8)的内容类型不匹配。如果使用自定义编码器,请确保正确实现 IsContentTypeSupported 方法。响应的前 1024 个字节为:“<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>IIS 7.5 详细错误 - 500.19 - Internal Server Error</title>
<style type="text/css">
<!--
body{margin:0;font-size:.7em;font-family:Verdana,Arial,Helvetica,sans-serif;background:#CBE1EF;}
code{margin:0;color:#006600;font-size:1.1em;font-weight:bold;}
.config_source code{font-size:.8em;color:#000000;}
pre{margin:0;font-size:1.4em;word-wrap:break-word;}
ul,ol{margin:10px 0 10px 40px;}
ul.first,ol.first{margin-top:5px;}
fieldset{padding:0 15px 10px 15px;}
.summary-container fieldset{padding-bottom:5px;margin-top:4px;}
legend.no-expand-all{padding:2px 15px 4px 10px;margin:0 0 0 -12px;}
legend{color:#333333;padding:4px 15px 4px 10px;margin:4px 0 8px -12px;_margin-top:0px;
border-top:1px solid #EDEDED;border-left:1px solid #EDEDED;border-right:1px solid #969696;
border-bottom:1px solid #969696;background:#E7ECF0;font-weight:bold;fo”。

请问,这是怎么回事呢?怎么办呢???

 回复 引用 查看   
#466楼[楼主] 2012-02-10 09:06 Artech      
“svc”“web.config”和Debug编译路径怎么可能会有关系呢?
 回复 引用 查看   
#467楼 2012-02-10 15:49 fengbeiwang      
http://127.0.0.1:9999/calculatorservice/metadata
客户端调用老是出现这个错误,是哪里出了问题,求大神解

评论共5页: 上一页 1 2 3 4 5 
发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 656901 c2CEsr59uPw=