title: WCF Newbie: Create a WCF Proxy to connect to old ASMX Web Service
body: <p>I am currently assigned on a task where I need to create a WCF that will act as a proxy to 3 ASMX services. Currently these services are consumed directly by several applications. </p>
  
  <p>Reason for building this WCF proxy is that it would be easier for us to update the asmx certificates in just one point of entry (the WCF proxy service) rather than several applications. </p>
  
  <p>I've created an ordinary .NET class library that basically creates a singleton instance for the ASMX service, but I'm not sure how I could expose it in a WCF service. </p>
  
  <p>Would it be possible if you could point me out where I could see excamples of a WCF acting as a proxy for consuming ASMX services?</p>
  
  <p>Below is my code:</p>
  
  <pre><code>public static class Service&lt;T&gt; where T : WebServicesClientProtocol
  {
      static volatile T _Instance;
      static volatile int _NumberOfReference = 0;
      static object syncRoot = new object();
  
      static Service() { }
  
      public static T Instance
      {
          get
          {
              if (_Instance == null)
              {
                  lock (syncRoot)
                  {
                      if (_Instance == null)
                      _Instance = ServiceProxyHelper.CreateServiceProxy&lt;T&gt;(ConfigValueHelper.GetServiceUrl(typeof(T).Name), ConfigValueHelper.CertificateHashKey);
                  }
              }
              return _Instance;
          }
      }
  }
  </code></pre>
  
  <p>And this is the helpers that I use:</p>
  
  <pre><code>public static class ServiceProxyHelper
  {
      public static T CreateServiceProxy&lt;T&gt;(string url, string clientBase64KeyId)
      {
          var webService = SetSecurityCredentials(clientBase64KeyId, url, typeof(T));
  
          if (webService == null)
              return default(T);
  
          return (T)Convert.ChangeType(webService, typeof(T));
      }
  
      private static WebServicesClientProtocol SetSecurityCredentials(string clientBase64KeyId, string url, Type serviceType)
      {
          WebServicesClientProtocol result = null;
  
          result = (WebServicesClientProtocol)Activator.CreateInstance(serviceType, true);
          result.Url = url;
  
          //Verify default credentials
          if (WebRequest.DefaultWebProxy != null)
          {
              result.Proxy = WebRequest.DefaultWebProxy;
              result.Credentials = CredentialCache.DefaultCredentials;
              result.Proxy.Credentials = CredentialCache.DefaultNetworkCredentials;
          }
  
          //Add security credentials to SOAP envelope
          var token = ServiceProxyHelper.GetSecurityToken(clientBase64KeyId, url);
  
          if (token == null)
              return null;
  
          result.RequestSoapContext.Security.Tokens.Add(token);
          result.RequestSoapContext.Security.Elements.Add(new MessageSignature(token));
  
          return result;
      }
  
      private static X509SecurityToken GetSecurityToken(string clientBase64KeyId, string url)
      {
          X509SecurityToken result = null;
          X509Certificate x509Certificate = null;
  
          var store = X509CertificateStore.CurrentUserStore(X509CertificateStore.MyStore);
          var isOpen = store.OpenRead();
  
          foreach (X509Certificate certificate in store.Certificates)
          {
              if (Convert.ToBase64String(certificate.GetKeyIdentifier()) != clientBase64KeyId)
                  continue;
  
              x509Certificate = certificate;
              result = new X509SecurityToken(certificate);
              break;
          }
  
          if (isOpen)
              store.Close();
  
          return result;
      }
  }
  </code></pre>