对于WCF一直都是只知其然,公司框架的架构者也只是对我们授之以鱼,而不授之以渔。

带着初学者的态度进入了大神Artech的博客,逐步慢慢上手。

我的解决方案(和大神的一模一样,只是过程中一波三折的)

  • Clients:客户端控制台程序,需要引用(System.ServiceMode),并在此项目中创建与WCF的通信。
  • Contracts:契约项目(我是右键解决方案->添加->新建项目->WCF服务库进行创建,这样好像就不用引用System.ServiceMode,它会自动引用),这个项目的就是对外公开的服务层,里面都是接口。
  • Hosting:WCF寄宿控制台程序,主要是搭载WCF服务(和IIS与windows服务性质一样)
  • Services:对Contracts里面方法的实现(也就是WCF方法的实现) ,这个项目是一个类库。

起步的项目很简单,就是照抄大神的功能,整个项目结构:

1,契约(Contracts)里面的WCF服务接口

public interface ICalculator
{
    [OperationContract]
    double Add(double x, double y);

    [OperationContract]
    double Subtract(double x, double y);

    [OperationContract]
    double Multiply(double x, double y);

    [OperationContract]
    double Divide(double x, double y);
}

2,WCF服务实现库Services,对契约的具体实现

public class CalculatorService : ICalculator
{
    public double Add(double x, double y) { return x + y; }

    public double Subtract(double x, double y) { return x - y; }

    public double Multiply(double x, double y) { return x * y; }

    public double Divide(double x, double y) { return x / y; }
}

3,宿主项目中对于服务的配置(在控制台程序中新建app.config配置文件进行配置)

<system.serviceModel>
  <behaviors>
    <serviceBehaviors>
      <behavior name="metadataBehavior">
        <serviceMetadata httpGetEnabled="true" />
      </behavior>
    </serviceBehaviors>
  </behaviors>
  <services>
    <service behaviorConfiguration="metadataBehavior" name="CalculatorService">
      <endpoint binding="wsHttpBinding" contract="Contracts.ICalculator" />
      <endpoint binding="netTcpBinding" contract="Contracts.ICalculator" />
      <host>
        <baseAddresses>
          <add baseAddress="http://localhost:9527/calculatorservice/ser" />
          <add baseAddress="net.tcp://localhost:9528/calculatorservice/ser" />
        </baseAddresses>
      </host>
    </service>
  </services>
</system.serviceModel>

4,控制台进行寄宿

using (ServiceHost host = new ServiceHost(typeof(CalculatorService)))
{
    host.Opened += delegate
    {
        Console.WriteLine("CalculaorService已经启动,按任意键终止服务!");
    };
    host.Open();
    Console.Read();

}

然后开始了旅程…

糟糕的过程一:将WCF寄宿到控制台

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

上述错误困扰了我近一个小时,到处找资料Google与百度都瞅遍了,什么样答案都能找到!对我就是木有用。

折腾了许久后,去泡了杯茶,回来后竟然就… 原来折腾我老久的问题是我自己给弄出来的。

在将服务给提供服务的主机 ServiceHost CalculatorService是引入了命名空间的,然而在配置文件中进行服务名称配置时确实这样的:

<service behaviorConfiguration="metadataBehavior" name="CalculatorService">

当给服务名称 加上命名空间后 就一切正常了

<service behaviorConfiguration="metadataBehavior" name="Services.CalculatorService">

顿时 ………

糟糕的过程二:客服端建立WCF通信

Error:【响应消息的内容类型 text/html; charset=utf-8 与绑定(text/xml; charset=utf-8)的内容类型不匹配。】

这个错误也折腾了我许久。错误是说内容类型不匹配,网上说要新建一个绑定

<bindings>
    <basicHttpBinding>
        <binding name="defaultHttpBinding" />
    </basicHttpBinding>
</bindings>

让后在终结点绑定bindingConfiguration

<endpoint address="http://localhost:9527/calculatorservice/ser" binding="basicHttpBinding" bindingConfiguration="defaultHttpBinding" contract="Contracts.ICalculator" name="hostEndpoint_http" />

照着试了下,完全没有效果,进入反思再反思,想着肯定是不是配置的问题,然后一遍遍检查,破绽便出现了(也怪自己不够细心)

在寄宿控制台的配置文件中绑定的是wsHttpBinding:

<endpoint binding="wsHttpBinding" contract="Contracts.ICalculator" />

而在客服端(Clients)配置文件中绑定的却是basicHttpBinding---->

<basicHttpBinding>
    <binding name="defaultHttpBinding" />
</basicHttpBinding>

解决方案是将客服端(Clients)配置文件改成wsHttpBinding:

<wsHttpBinding>
  <binding name="defaultHttpBinding" />
</wsHttpBinding>

最后客服端配置文件中的客服端配置为:

<system.serviceModel>
  <bindings>
    <netTcpBinding>
      <binding name="defaultTcpBinding" />
    </netTcpBinding>
    <wsHttpBinding>
      <binding name="defaultHttpBinding" />
    </wsHttpBinding>
  </bindings>
  <client>
    <endpoint address="http://localhost:9527/calculatorservice/ser"
              binding="wsHttpBinding"
              bindingConfiguration="defaultHttpBinding"
              contract="Contracts.ICalculator"
              name="hostEndpoint_http" />
    <endpoint address="net.tcp://localhost:9528/calculatorservice/ser"
              binding="netTcpBinding"
              bindingConfiguration="defaultTcpBinding"
              contract="Contracts.ICalculator"
              name="hostEndpoint_tcp" />
  </client>
</system.serviceModel>

一切准备就绪,接下来开始建立WCF 通信将这些通道将消息发送到不同配置的服务终结点。

var channel = new ChannelFactory<ICalculator>("hostEndpoint_http").CreateChannel();
var d = channel.Add(1.2, 2.5);

OK ,完事。

走进WCF一 (异常如此多娇,引无数码农竞折煞)的更多相关文章

  1. Wcf Client 异常和关闭的通用处理方法

    在项目中采用wcf通讯,客户端很多地方调用服务,需要统一的处理超时和通讯异常以及关闭连接. 1.调用尝试和异常捕获 首先,项目中添加一个通用类ServiceDelegate.cs public del ...

  2. WCF常见异常-The maximum string content length quota (8192) has been exceeded while reading XML data

    异常信息:The maximum string content length quota (8192) has been exceeded while reading XML data 问题:调用第三 ...

  3. 利用Attribute和IErrorHandler处理WCF全局异常

    在处理WCF异常的时候,有大概几种方式: 第一种是在配置文件中,将includeExceptionDetailInFaults设置为true <behavior name="servi ...

  4. WCF调试异常信息:ServiceHost 仅支持类服务类型

    "/CommonHelpServices"应用程序中的server错误. ServiceHost 仅支持类服务类型. 说明: 运行当前 Web 请求期间,出现未经处理的异常. 请检 ...

  5. 使用svctraceviewer查看WCF服务异常信息

    这两天遇到一个问题,调用一个WCF服务的时候,服务器端正常的返回了数据,但是客户端却遇到了一场 System.ServiceModel.CommunicationException: The unde ...

  6. WCF基础教程之异常处理:你的Try..Catch语句真的能捕获到异常吗?

    在上一篇WCF基础教程之开篇:创建.测试和调用WCF博客中,我们简单的介绍了如何创建一个WCF服务并调用这个服务.其实,上一篇博客主要是为了今天这篇博客做铺垫,考虑到网上大多数WCF教程都是从基础讲起 ...

  7. 十五天精通WCF——第十四天 一起聊聊FaultException

     我们在玩web编程的时候,可能你会不经意的见到一些http500的错误,我想你应该不会陌生的,原因你应该也知道,服务器异常嘛, 这时候clr会把这个未处理的异常抛给iis并且包装成http500的错 ...

  8. 三十、【C#.Net开发框架】WCFHosting服务主机的利用WCF服务通讯和实现思路

    回<[开源]EFW框架系列文章索引>        EFW框架源代码下载V1.3:http://pan.baidu.com/s/1c0dADO0 EFW框架实例源代码下载:http://p ...

  9. WCF 入门(15)

    前言 度过了一个阳光明媚的周末. 一个阴霾的周日夜晚. 第15集 WCF里面的异常处理(1)  Exception handling in WCF 大致看了一下,这个WCF视频里面总共有6集,这个是第 ...

随机推荐

  1. C#_dropdownlist_1

    关于ASP.net MVC 中DropDownList绑定与提交数据   在做 ASP.net MVC项目中,数据绑定也是很关键的,现在以个人经验与大家交流下 ASP.net MVC 中DropDow ...

  2. JQuery实现页面Loading效果

    第一步:添加遮罩层和LOADING层 <div class="overlay"></div><div id="AjaxLoading&quo ...

  3. C#开发-ftp操作方法整理

    1.整理简化了下C#的ftp操作,方便使用    1.支持创建多级目录    2.批量删除    3.整个目录上传    4.整个目录删除    5.整个目录下载 2.调用方法展示, var ftp ...

  4. C++ (P70—P96)

    1 类的成员默认为私有模型 2 类的声明内不允许对数据成员进行初始化 3 类的成员函数,如果在类外定义,只需在函数类型之前加上inline就为内联函数了,如果在类内定义函数则该函数自动成为内联成员函数 ...

  5. linux系统学习(常用命令)

    今天调休,闲来无事,研究一下linux系统. Linux常用命令: 一:文件管理 ctrl+alt:在虚拟机与windows之间切换ctrl+g:进入linux输入模式 pwd:查看当前目录 ls:列 ...

  6. Linux编程简介

    Linux编程可以分为Shell(如BASH.TCSH.GAWK.Perl.Tcl和Tk等)编程和高级语言(C语言,C++语言,java语言等)编程,Linux程序需要首先转化为低级机器语言即所谓的二 ...

  7. iis7 php urlrewrite 并隐藏index.php

    <rewrite> <rules> <rule name="OrgPage" stopProcessing="true"> ...

  8. 用于主题检测的临时日志(fe4edac1-b4f4-4673-ae87-110cbb7dbb5a - 3bfe001a-32de-4114-a6b4-4005b770f6d7)

    这是一个未删除的临时日志.请手动删除它.(25ea5485-9168-424b-a30c-09cc1371e2d9 - 3bfe001a-32de-4114-a6b4-4005b770f6d7)

  9. ASP连接MYSQL数据库

    <% strconnection="driver={mysql odbc 3.51 driver};database=weste_net;server=localhost;uid=ro ...

  10. sqlserver 理解数据集

    数据集分四类: 1.A∩B,既是所求数据集既在A中,又在B中 2.A∪B,既所求数据在数据集A中,或在数据集B中 3.A-B,既所求数据在数据集A中,不在数据集B中 4.B-A,既所求数据在数据集B中 ...