Since the .NET Framework 3.0 June CTP should soon be upon us here is the updated version of the MetadataResolver code I gave in the last post. You'll see that it's a bit more concise and there is no longer a separate InfoCardClientCredentials class.

One thing to be aware of when you build a service with post-beta 2 bits is that mex is no longer on by default so you'll need an additional service endpoint for this code to actually be able to pull down mex from you WCF service:

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

I won't put all the code here but we'll be updating our code samples at http://wcs.netfx3.com when the June CTP hits the streets. You should also keep an eye out for some new features on the site to celebrate this build!

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.IdentityModel.Selectors;

namespace HelloClient
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Press <Enter> when service is ready");
            Console.ReadLine();
            try
            {               
                Uri mexUri = new Uri("http://localhost:4124/helloService/mex");
                ContractDescription contract = ContractDescription.GetContract(typeof(HelloService.IHello));
               
                EndpointAddress mexEndpointAddress = new EndpointAddress(mexUri);
                ServiceEndpointCollection endpoints = MetadataResolver.Resolve(contract.ContractType, mexEndpointAddress);
               
                foreach (ServiceEndpoint endpoint in endpoints)
                {
                    if (endpoint.Contract.Namespace.Equals(contract.Namespace) && endpoint.Contract.Name.Equals(contract.Name))
                    {
                        ChannelFactory<HelloService.IHello> cf = new ChannelFactory<HelloService.IHello>(endpoint.Binding, endpoint.Address);
                        cf.Credentials.ServiceCertificate.Authentication.RevocationMode = System.Security.Cryptography.X509Certificates.X509RevocationMode.NoCheck;
                        HelloService.IHello chn = cf.CreateChannel();
                        Console.WriteLine(chn.Say());
                        cf.Close();
                    }
                }
            }
            catch (UserCancellationException)
            {
                Console.WriteLine("User cancelled");
            }
            catch (UntrustedRecipientException)
            {
                Console.WriteLine("User does not trust the recipient");
            }
            catch (ServiceNotStartedException)
            {
                Console.WriteLine("CardSpace service not started");
            }
            catch (InfoCardException ice)
            {
                Console.WriteLine("Generic CardSpace exception :" + ice.Message);
            }
            catch (Exception e)
            {
                Console.WriteLine("Other exceptions :" + e.Message);
            }
            finally
            {
                Console.WriteLine("Press any key to finish");
                Console.ReadKey();
            }
        }
    }
}