开发者

Adding a service reference to a WCF service with webHttpBinding and security mode Transport results in an incorrect config file

I have searched and searched and I cannot find a solution. It seems like it would be relatively common to run into this... WCF REST service over https. When I add the service reference all of the proxy classes are correct and I can create the objects defined in the service, call the services, etc. However, I can't create a configured client with the proxy's client classes. I have to explicity create the bindings, behaviors, and endpoints and add them to the client. FOr example, what I should be able to do, based on all of my research is:

ServiceClient = new ServiceClient();

And be off and running. However, what I have to do is:

WebHttpBinding serviceBinding = new WebHttpBinding(WebHttpSecurityMode.Transport);
serviceBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
EndpointAddress endPointAddress
            = new EndpointAddress(<endpointaddress>);

// Create Service Client 
ServiceClient = new ServiceClient(serviceBinding, endPointAddress);

// Add Web Behavior to the EndPoint
WebHttpBehavior webHttpBehavior = new WebHttpBehavior();
ServiceClient.Endpoint.Behaviors.Add(webHttpBehavior);

// Set up the request to POST with a wrapped request
WebInvokeAttribute postAttribute = new WebInvokeAttribute();
postAttribute.Method = "POST";
postAttribute.BodyStyle = WebMessageBodyStyle.WrappedRequest;
ServiceClient.Endpoint.Contract.Operations.Find(<operationname>).Behaviors.Add(postAttribute);

In order to mimic the service configuration:

<behaviors>
      <endpointBehaviors>
        <behavior name="AspNetAjaxBehaviorXml">
          <webHttp />
        </behavior>
      </endpointBehaviors>
       <serviceBehaviors>
          <behavior name="AuthenticationServicesBehavior">
            <serviceMetadata httpsGetEnabled="true" policyVersion="Policy15" />
            <serviceDebug includeExceptionDetailInFaults="true" />
          </behavior>
          <behavior name="LoggingServicesBehavior">
             <serviceMetadata httpsGetEnabled="true" policyVersion="Policy15" />
             <serviceDebug includeExceptionDetailInFaults="true" />
          </behavior>
       </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="True" />
    <bindings>
      <webHttpBinding>
        <binding name="WebSslBinding">
          <security mode="Transport">
            <transport clientCredentialType="None" />
          &l开发者_开发百科t;/security>
        </binding>
      </webHttpBinding>
    </bindings>
    <services>
       <service behaviorConfiguration="AuthenticationServicesBehavior"
          name="AuthenticationServices">
          <endpoint address="authenticate" behaviorConfiguration="AspNetAjaxBehaviorXml"
             binding="webHttpBinding" bindingConfiguration="WebSslBinding"
             name="AuthenticationEndPoint" bindingNamespace="<mynamespace>"
             contract="IService" />
       </service>

The "Add Service Reference" is giving me this:

<bindings>
   <customBinding>
    <binding name="AuthenticationEndPoint">
     <!--    WsdlImporter encountered unrecognized policy assertions in ServiceDescription 'EchoAppsServices':    -->
     <!--    <wsdl:binding name='AuthenticationEndPoint'>    -->
     <!--        <sp:HttpsToken xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">..</sp:HttpsToken>    -->
     <textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
      messageVersion="Soap12" writeEncoding="utf-8">
      <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
       maxBytesPerRead="4096" maxNameTableCharCount="16384" />
     </textMessageEncoding>
    </binding>
   </customBinding>
  </bindings>
  <client>
   <endpoint binding="customBinding" bindingConfiguration="AuthenticationEndPoint"
    contract="AuthenticationService"
    name="AuthenticationEndPoint" />
  </client>

I believe my inability to create a default client that works out of the box is related to the problem with WsdlImporter. I get a similar error when I use svcutil:

Warning: The following Policy Assertions were not Imported:
  XPath://wsdl:definitions[@targetNamespace='<mynamespace>']/wsdl:binding[@na
me='AuthenticationEndPoint']
  Assertions:
    <sp:HttpsToken xmlns:sp='http://schemas.xmlsoap.org/ws/2005/07/securitypolic
y'>..</sp:HttpsToken>

I'm sure it has something to do with my self signed cert, but I can't get makecert to give me a functioning cert with a CA that doesn't cause my IIS to crash.

Environment details: VS2008 XP 64bit .NET 3.5 IIS6

Thanks in advance for any help...


If you want to create client proxy classes, why would you use webHttpBinding. Why not just use wsHttpBinding?

The whole point of webHttpBinding was so that you could use standard Http toolkits like HttpWebRequest and Microsoft.Http.HttpClient on the client to access the service.


Not sure if that's just a typo - but your code and config don't match.

See in your code:

serviceBinding.Security.Transport.ClientCredentialType = 
      HttpClientCredentialType.Windows;

but in your config:

<webHttpBinding>
    <binding name="WebSslBinding">
      <security mode="Transport">
        <transport clientCredentialType="None" />
      </security>
    </binding>
</webHttpBinding>

In code, you set your HttpClientCredentialType to Windows (integrated Windows authentication), but in config, you set it to None.

Try changing your config to use Windows as well:

      <security mode="Transport">
        <transport clientCredentialType="Windows" />
      </security>

and try again.

If you don't get any better results : why not just update the client config manually, after the import? The WSDL importer is known to have hiccups here and there, and most often, just using your brain and manual config adaption can solve the problem. You basically just need to copy the <endpointBehaviors> and the <bindings> sections into your client side config and define a <client> section which references the appropriate endpoint - that's pretty much all.


You bring up a good point, but I started down this road to make a RESTful web service that can be called either from the client or the server. I can call it from both right now just the way it is but I have to explicitly configure the server side. This is unacceptable because this application will be deployed to multiple end users and it's easier to change a configuration file than it is to patch. I know that I could create multiple endpoints, but I would much rather only have to maintain one per service. Thank you for your reply.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜