以编程方式定义带有行为的WCF端点

时间:2016-06-03 22:49:42

标签: c# web-services wcf

有人能告诉我如何以编程方式创建具有端点行为的WSHttpBindings吗?

这是从WCF添加服务引用到6个WebServices生成的内容,我手动编辑它以添加行为,以便所有端点使用相同的行为。

<system.serviceModel>
  <behaviors>
    <endpointBehaviors>
      <behavior name="epBehaviour">
        <clientCredentials>
          <clientCertificate findValue="This is my TEST Cert" storeLocation="LocalMachine" x509FindType="FindBySubjectName" storeName="My" />
        </clientCredentials>
      </behavior>
    </endpointBehaviors>
  </behaviors>
  <bindings>
    <wsHttpBinding>
      <binding name="WSHttpBinding_IQuote" messageEncoding="Mtom">
        <security mode="TransportWithMessageCredential">
          <transport clientCredentialType="None" />
          <message clientCredentialType="Certificate" establishSecurityContext="false" />
        </security>
      </binding>
      <binding name="WSHttpBinding_ICommit" messageEncoding="Mtom">
        <security mode="TransportWithMessageCredential">
          <transport clientCredentialType="None" />
          <message clientCredentialType="Certificate" establishSecurityContext="false" />
        </security>
      </binding>
      <binding name="WSHttpBinding_IRetrieve" messageEncoding="Mtom">
        <security mode="TransportWithMessageCredential">
          <transport clientCredentialType="None" />
          <message clientCredentialType="Certificate" establishSecurityContext="false" />
        </security>
      </binding>
      <binding name="WSHttpBinding_IInfo" messageEncoding="Mtom">
        <security mode="TransportWithMessageCredential">
          <transport clientCredentialType="None" />
          <message clientCredentialType="Certificate" establishSecurityContext="false" />
        </security>
      </binding>
      <binding name="WSHttpBinding_IPurge" messageEncoding="Mtom">
        <security mode="TransportWithMessageCredential">
          <transport clientCredentialType="None" />
          <message clientCredentialType="Certificate" establishSecurityContext="false" />
        </security>
      </binding>
      <binding name="WSHttpBinding_ISearch" messageEncoding="Mtom">
        <security mode="TransportWithMessageCredential">
          <transport clientCredentialType="None" />
          <message clientCredentialType="Certificate" establishSecurityContext="false" />
        </security>
      </binding>
    </wsHttpBinding>
  </bindings>
  <client>
    <endpoint address="https://my.service.com/WCFServices/Info.svc" behaviorConfiguration="epBehaviour" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IInfo" contract="InfoWcfWS.IInfo" name="WSHttpBinding_IInfo" />
    <endpoint address="https://my.service.com/WCFServices/Quote.svc" behaviorConfiguration="epBehaviour" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IQuote" contract="QuoteWcfWS.IQuote" name="WSHttpBinding_IQuote" />
    <endpoint address="https://my.service.com/WCFServices/Commit.svc" behaviorConfiguration="epBehaviour" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ICommit" contract="CommitWcfWS.ICommit" name="WSHttpBinding_ICommit" />
    <endpoint address="https://my.service.com/WCFServices/Retrieve.svc" behaviorConfiguration="epBehaviour" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IRetrieve" contract="RetrieveWcfWS.IRetrieve" name="WSHttpBinding_IRetrieve" />
    <endpoint address="https://my.service.com/WCFServices/Purge.svc" behaviorConfiguration="epBehaviour" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IPurge" contract="PurgeWcfWS.IPurge" name="WSHttpBinding_IPurge" />
    <endpoint address="https://my.service.com/WCFServices/Search.svc" behaviorConfiguration="epBehaviour" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ISearch" contract="SearchWcfWS.ISearch" name="WSHttpBinding_ISearch" />
  </client>
</system.serviceModel>

目前使用“添加服务”生成的代理并将端点中引用的行为“epBehaviour”添加​​为behaviorviourConfiguration,我可以调用端点。

现在,我的下一步是将行为部分和URL定义为配置(可能位于web.config中),以便我可以为分段和生产配置不同的配置。

所以我的示例Staging配置将具有如下定义的URL

<appSettings>
  <add key="ServiceUrl.Tls12.Quote" value="https://my.service.com/WCFServices/Quote.svc" />
  <add key="ServiceUrl.Tls12.Commit" value="https://my.service.com/WCFServices/Commit.svc" />
  <add key="ServiceUrl.Tls12.Retrieve" value="https://my.service.com/WCFServices/Retrieve.svc" />
  <add key="ServiceUrl.Tls12.Info" value="https://my.service.com/WCFServices/Info.svc" />
  <add key="ServiceUrl.Tls12.Purge" value="https://my.service.com/WCFServices/Purge.svc" />
  <add key="ServiceUrl.Tls12.Search" value="https://my.service.com/WCFServices/Search.svc" />
</appSettings>

因此,如果我使用“Info”WebService,我的代码应该是

//Code is missing how to define all the specifics like behaviours.
WSHttpBinding binding = new WSHttpBinding();
                EndpointAddress endpoint = new EndpointAddress(new Uri(ConfigurationManager.AppSettings["ServiceUrl.Tls12.Info"]));
             InfoWcfWS.InfoClient proxyNew = new InfoWcfWS.InfoClient(binding, endpoint);

总结一下,鉴于在“添加服务”之后生成的配置,为了生成我的代理类,我想删除VS生成的所有配置并定义我自己的配置,该配置将保存URL;其他一些像端点URI,行为..等等应该以编程方式实例化。

由于

2 个答案:

答案 0 :(得分:4)

您必须从System.ServiceModel.Description命名空间创建所需行为的实例,或者自己创建它们,然后将它们添加到ChannelFactory

对于您的示例,您可以为所需的界面和您喜欢的任何绑定创建area.write(fw); 。然后,您实例化ClientCredentials行为,配置您需要的任何设置,并将其添加到ChannelFactory的EndPointBehaviors。然后,您已准备好创建一个客户端通道,该通道将为您提供实现服务接口的对象。您可以使用与生成的客户端类似的内容。

ChannelFactory

答案 1 :(得分:2)

最后,我找到了一种更简单的方法 - 这是我正在访问的方法之一:

WSHttpBinding binding = new WSHttpBinding();
EndpointAddress endpoint = new EndpointAddress(new Uri("https://my.service.com/WCFServices/Info.svc"));


binding.Name = "WSHttpBinding_IInfo";
binding.MessageEncoding = WSMessageEncoding.Mtom;
binding.Security = new WSHttpSecurity();
binding.Security.Mode = SecurityMode.TransportWithMessageCredential;
binding.Security.Transport = new HttpTransportSecurity();
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
binding.Security.Message = new NonDualMessageSecurityOverHttp();
binding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
binding.Security.Message.EstablishSecurityContext = false;



InfoClient proxy = new InfoClient(binding, endpoint);


proxy.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My,                                                  X509FindType.FindBySubjectName, "This is my TEST Cert");

object response = proxy.ServiceMethod();