A: 

I haven't had any problems, but I went the "add service reference..." route which I had to do via "VS2010 Express for Windows Phone" b/c VS2010 RC doesn't yet support that feature for WP7 development. The Express version comes with the WP7 Developer's install.

scottmarlowe
Yes, that's what I found as well. I've actually almost got to the point where I can get hand crafted code to run. Will post later.
Igor Zevaka
+5  A: 

As scottmarlowe pointed out, the automagicly generated service refrence just works. I have set upon the mission to work out just why the bloody hell it works and the manual version doesn't.

I found the culprit and it is ChannelFactory. For some reason new ChannelFactory<T>().CreateChannel() just throws an exception. The only solution I found is to provide your own implementation of the channel. This involves:

  1. Override ClientBase. (optional).
  2. Override ClientBase.CreateChannel. (optional).
  3. Subclass ChannelBase with a specific implementation of your WCF interface

Now, ClientBase already provides an instance of the channel factory thru ChannelFactory property. If you simply call CreateChannel off that you would get the same exception. You need to instantiate a channel that you define in step 3 from within CreateChannel.

This is the basic wireframe of how it all looks put together.

[DataContractAttribute]
public partial class AuthenticationResponse {
[DataMemberAttribute]
public bool Success {
    get; set;
}

[System.ServiceModel.ServiceContract]
public interface IAuthentication
{
    [System.ServiceModel.OperationContract(AsyncPattern = true)]
    IAsyncResult BeginLogin(string user, string password, AsyncCallback callback, object state);
    AuthenticationResponse EndLogin(IAsyncResult result);
}

public class AuthenticationClient : ClientBase<IAuthentication>, IAuthentication {

    public IAsyncResult BeginLogin(string user, string password, AsyncCallback callback, object asyncState)
    {
        return base.Channel.BeginLogin(user, password, callback, asyncState);
    }

    public AuthenticationResponse EndLogin(IAsyncResult result)
    {
        return Channel.EndLogin(result: result);
    }

    protected override IAuthentication CreateChannel()
    {
        return new AuthenticationChannel(this);
    }

    private class AuthenticationChannel : ChannelBase<IAuthentication>, IAuthentication
    {
        public AuthenticationChannel(System.ServiceModel.ClientBase<IAuthentication> client)
        : base(client)
        {
        }

        public System.IAsyncResult BeginLogin(string user, string password, System.AsyncCallback callback, object asyncState)
        {
            object[] _args = new object[2];
            _args[0] = user;
            _args[1] = password;
            System.IAsyncResult _result = base.BeginInvoke("Login", _args, callback, asyncState);
            return _result;
        }

        public AuthenticationResponse EndLogin(System.IAsyncResult result)
        {
            object[] _args = new object[0];
            AuthenticationResponse _result = ((AuthenticationResponse)(base.EndInvoke("Login", _args, result)));
            return _result;
        }
    }
}

TLDR; If you want to use your own WCF code on WP7 you need to create your own channel class and not rely on ChannelFactory.

Igor Zevaka
+1  A: 

Dynamic proxy creation using ChannelFactory.CreateChannel() is not supported on Windows Phone. This is documented here - http://msdn.microsoft.com/en-us/library/ff426930(VS.96).aspx

Consuming a service using the 'Add service reference' mechanism in a async pattern would be the correct way to do.

Vijay Verma
+1  A: 

I put a blog post together on this very subject: http://blogs.msdn.com/b/andypennell/archive/2010/09/20/using-wcf-on-windows-phone-7-walk-through.aspx

Andy Pennell