Friday, May 20, 2016

Support high volume data transfer by WCF service

Sometime the requirement is send big data to WCF service from client, basically looking for option to send high data through the wire.

WCF can support up to 2 GB data through the wire; even though it is not recommended.

To enable this we need to set some attributes to binding tags in Server and Client side config file

Server Config File
<bindings>
   <wsHttpBinding>
     <binding name="wsHttpBindingSettings" maxReceivedMessageSize="2147483647">
       <readerQuotas
              maxDepth="2147483647"
              maxStringContentLength="2147483647"
              maxArrayLength="2147483647"
              maxBytesPerRead="2147483647"
              maxNameTableCharCount="2147483647"/>
      </binding>
   </wsHttpBinding>
</bindings>

<endpoint
address=""
binding="wsHttpBinding"
contract="WcfService1.IService1"
bindingConfiguration="wsHttpBindingSettings">      

Client Config File 

<bindings>
  <wsHttpBinding>
     <binding
name="WSHttpBinding_IService1"
maxBufferPoolSize="2147483647"
              maxReceivedMessageSize="2147483647">
      <readerQuotas
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
              maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
     </binding>
  </wsHttpBinding>

</bindings>
   <endpoint
address="http://localhost:59284/Service1.svc"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IService1" 
contract="ServiceReference1.IService1"
       name="WSHttpBinding_IService1">

Thursday, May 19, 2016

The client certificate is not provided. specify a client certificate in clientcredentials.

I have done all the setup; require to setup WCF message security and tried calling service from client, is working fine without any issues.
later I made few changes on the service and again use 'Update Service Reference' to update my service. suddenly service stop working and gave below error
 "The client certificate is not provided. specify a client certificate in clientcredentials."

Cause
As soon as I did service update; client side config file updated with new endpoint section, that removed (custom) one attribute 'behaviorConfiguration'.

Solution
After updating the service reference add 'behaviorConfiguration' attribute to endpoint section like below

<endpoint 
address="http://localhost:65514/Service1.svc" 
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IService1" 
contract="ServiceReference1.IService1"

name="WSHttpBinding_IService1"
behaviorConfiguration="CustomBehavior">

If you have added any kinds of attributes; that will be removed after you update service using 'Update Service Reference'.

The caller was not authenticated by the service. WCF with Certificate Credential

After setting all section in the config file everything works, but when I tried to call service from client then I got error "The caller was not authenticated by the service.

Cause

The problem was Client and Server Certificates (WcfServer & WcfClient) was on

In MMC
Console Root à Certificate Current User à Personal à Certificates
But NOT in
Console Root à Certificate Current User à Trusted People à Certificates

Solution
  • In MMC
  • Copy both certificates 
  • From: Console Root à Certificate Current User à Personal à Certificates
  • TO:    Console Root à Certificate Current User à Trusted People à Certificates

After done this it’s solve my problem.

How to set Security (Certificate) in WCF service, 9 simple steps are here

Create certificate by using makecert.exe
  • makecert.exe -sr CurrentUser -ss My -a sha1 -n CN=WcfServer -sky exchange -pe
  • makecert.exe -sr CurrentUser -ss My -a sha1 -n CN=WcfClient -sky exchange -pe

Mostly we have to set following sections in Server and Client Config files
  • services
  • behaviors
  • bindings
  • endpointBehaviors

 WCF Server Config
<services>
  <service name="WcfService1.Service1" behaviorConfiguration="wsHttpServices">
          <endpoint address=""
                    binding="wsHttpBinding"
                    bindingConfiguration="wsHttpBinding_config"
                    contract="WcfService1.IService1">
          </endpoint>
        </service>
</services>

<behaviors>
      <serviceBehaviors>
        <behavior name="wsHttpServices">
>
  <clientCertificate>
         <authentication certificateValidationMode="PeerTrust"/>
  </clientCertificate>
        <serviceCertificate
findValue="WcfServer"
storeLocation="CurrentUser"
storeName="My" 
x509FindType="FindBySubjectName" >
</serviceCertificate>
 </serviceCredentials>
      </behavior>
   </serviceBehaviors>
</behaviors>

<bindings>
      <wsHttpBinding>
        <binding name="wsHttpBinding_config">
          <security mode="Message">
            <message clientCredentialType="Certificate"/>
          </security>
        </binding>
      </wsHttpBinding>
</bindings>

WCF Client Config
<client>
      <endpoint address="http://localhost:65514/Service1.svc"
              binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1"
contract="ServiceReference1.IService1" behaviorConfiguration="CustomBehavior"
              name="WSHttpBinding_IService1">
        <identity>
<dns value="WcfServer"/>         
        </identity>
      </endpoint>
</client>

<endpointBehaviors>
        <behavior name="CustomBehavior">
          <clientCredentials>
            <clientCertificate
findValue="WcfClient" x509FindType="FindBySubjectName" storeLocation="CurrentUser" storeName="My"/>
            <serviceCertificate>
              <authentication certificateValidationMode="PeerTrust"/>
            </serviceCertificate>
          </clientCredentials>
        </behavior>
</endpointBehaviors>

<bindings>
      <wsHttpBinding>
        <binding name="WSHttpBinding_IService1">
          <security>
            <message clientCredentialType="Certificate" />
          </security>
        </binding>
      </wsHttpBinding>
 </bindings>