• 整理一下思路,探讨WCF(二)


    基于上文的Demo,我们观察到,在IIS宿主中,配置文件有以下特征:

    <system.serviceModel>
      <services>
        <service name="WcfService9.Service1" behaviorConfiguration="WcfService9.Service1Behavior">
          <endpoint address="" binding="wsHttpBinding" contract="WcfService9.IService1">
            <identity>
              <dns value="localhost"/>
            </identity>
          </endpoint>
          <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        </service>
      </services>
      <behaviors>
        <serviceBehaviors>
          <behavior name="WcfService9.Service1Behavior">
            <serviceMetadata httpGetEnabled="true"/>
            <serviceDebug includeExceptionDetailInFaults="false"/>
          </behavior>
        </serviceBehaviors>
      </behaviors>
    </system.serviceModel>

    下面修改这个配置文件,看怎么搞死WCF:

    1.删除MEX终结点:

    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>

    一切照常,Service可以运行,Client也可以调用Service的方法。

    image

    image

    2.不删除MEX终结点,只删除行为中的serviceMetadata 标签:

    <serviceMetadata httpGetEnabled="true"/>

    会发现Service不能运行,更不要说Client能调用Service了。

    image

    具体异常信息如下所示:

    The contract name 'IMetadataExchange' could not be found in the list of contracts implemented by the service Service1.  Add a ServiceMetadataBehavior to the configuration file or to the ServiceHost directly to enable support for this contract.

    3.怎么办?干脆连MEX那一行也删了,新的配置文件如下所示:

        <system.serviceModel>
            <services>
                <service name="WcfService9.Service1" behaviorConfiguration="WcfService9.Service1Behavior">
                    <!-- Service Endpoints -->
                    <endpoint address="" binding="wsHttpBinding" contract="WcfService9.IService1">
                        <identity>
                            <dns value="localhost"/>
                        </identity>
                    </endpoint>
                </service>
            </services>
            <behaviors>
                <serviceBehaviors>
                    <behavior name="WcfService9.Service1Behavior">
                        <serviceDebug includeExceptionDetailInFaults="false"/>
                    </behavior>
                </serviceBehaviors>
            </behaviors>
        </system.serviceModel>
    

    于是,Service又能运行了,

    image

    但是,因为没有公布MEX元数据交换中间点,所以,我们不能在Client端添加对Service的引用:

    image

    4.好吧,看来我们要想在httpGetEnabled上做文章,只能保留MEX终结点。既然删除<serviceMetadata httpGetEnabled="true"/> 这个标签会导致Service不能运行,我们在删除httpGetEnabled属性的同时,保留这个标签,如下所示:

      <system.serviceModel>
        <services>
          <service name="WcfService9.Service1" behaviorConfiguration="WcfService9.Service1Behavior">
            <endpoint address="" binding="wsHttpBinding" contract="WcfService9.IService1">
              <identity>
                <dns value="localhost"/>
              </identity>
            </endpoint>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
          </service>
        </services>
        <behaviors>
          <serviceBehaviors>
            <behavior name="WcfService9.Service1Behavior">
              <serviceMetadata/>
              <serviceDebug includeExceptionDetailInFaults="false"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>
    

    我们发现,Service又能运行了,但是http://localhost:40159/Service1.svc页面与前面成功运行起来的页面不太一样:

    image

    尽管如此,我们还是能够正常使用这个Service:

    image

    5.哦,原来是这样。看来<serviceMetadata httpGetEnabled="true"/>是不能赶尽杀绝的,至少要保留一个<serviceMetadata/>标签。

    我们将配置文件修改为:

    <serviceMetadata httpGetEnabled="false"/>

    ,再次运行Service,会发现和<serviceMetadata/>具有相同的效果。可见,httpGetEnabled默认值为false。

    6.我们在第4次测试中,发现<serviceMetadata httpGetEnabled="true"/><serviceMetadata httpGetEnabled="false"/>所产生的Service页面不同:

    image

    image

    但是,Client都是可以调用Service的。那么差异到底在哪里呢?

    经测试,在MEX终结点存在的情况下,是否设置httpGetEnabled是没有区别的。

    但是,如果删除MEX终结点,差异就出来了:

    对于<serviceMetadata httpGetEnabled="true"/>,我们发现,Service可以运行,Client也可以调用Service。

    而对于<serviceMetadata httpGetEnabled="false"/>,这就是测试3的情形了,Service虽然可以运行,但是因为没有公布元数据终结点,所以Client不能调用Service。

    好了,可以结案陈词了。

    MEX和httpGetEnabled是公布元数据终结点的两种不同方式。

    MEX可以适用于任何binding,比如说TCP、HTTP。

    httpGetEnabled则仅适用于HTTP。

    那好,既然我们现在就处于IIS宿主的环境下,那么二者就都可以使用。

    1)只设置MEX是不够的,在此基础上,我们还要设置httpGetEnabled="true"

    2)只设置<serviceMetadata httpGetEnabled="true"/>就够了。

    此外,最恶心的莫过于,如果不设置<serviceMetadata httpGetEnabled="true"/>,但是仍然要保留<serviceMetadata>标签。我猜,这也许源于自定义behavior的设计原理。在配置文件中必须要声明这个标签,哪怕是一个空标签,也要保留,从而在WCF运行起来的时候,会找到这个serviceMetadata标签,进行实例化(设置httpGetEnabled默认值为false)。

    此时,我已经能想象到WCF设计团队脸上的无奈了。

  • 相关阅读:
    win7 下加载MSCOMCTL.OCX
    getGLES1ExtensionString: Could not find GLES 1.x config!
    IUnknown(TVarData(Params[0]).VPointer) as Range
    win8 VB6打开提示MSCOMCTL.ocx未注册
    服务端接口处理流任务要如何返回?
    flink之kafka生产和消费实战-将生产数据存放到mongodb中
    初识doris的那些基本概念
    bash常见用法
    sonar p3c规则配置
    sonar之gitlab ci 在gradle项目的实践(汉化、branch、 commit提交评论)
  • 原文地址:https://www.cnblogs.com/Jax/p/1597885.html
Copyright © 2020-2023  润新知