MonoTouch WCF REST Ошибка при создании канала - PullRequest
5 голосов
/ 11 марта 2011

Я пытаюсь получить доступ к службам WCF REST через MonoTouch. Я не могу использовать ChannelFactory, так как динамическая генерация кода невозможна в MonoTouch, и, поскольку я обращаюсь к службам RESTful, я также не могу использовать svcutil для создания клиентских классов.

Это оставляет меня с созданием клиентских классов вручную. Я получил довольно далеко, но столкнулся с проблемой, вот мой код для прокси-класса:

public class AuthenticationClient : System.ServiceModel.ClientBase<IAuthenticationService>, IAuthenticationService
{
    public AuthenticationClient(Binding binding, EndpointAddress baseAddress) : base(binding, baseAddress)
    { } 

    public AuthenticationResult AuthenticateUser (AccountCredentials credentials)
    {
        return base.Channel.AuthenticateUser(credentials);
    }

    protected override IAuthenticationService CreateChannel ()
    {
        // This method must be overriden in MonoTouch to prevent using a ChannelFactory
        return new AuthenticationChannel(this);
    }

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

        public AuthenticationResult AuthenticateUser (AccountCredentials credentials)
        {
            object[] _args = new object[1];
            _args[0] = credentials;

            return (AuthenticationResult)base.Invoke("AuthenticateUser", _args); // Exception thrown here       
        }
    }   
}

Интерфейс IAuthenticationService использует атрибуты для указания конечной точки Uri:

[ServiceContract]
public interface IAuthenticationService
{
    [OperationContract]
    [WebInvoke(Method = "POST", UriTemplate = "/Authenticate/User")]
    AuthenticationResult AuthenticateUser(AccountCredentials credentials);
}

Вот как я использую прокси-класс:

var serviceHost = "http://mydomain.com/";
var servicePath = "Services/Authentication";

Uri hostUri = new Uri(serviceHost);
Uri serviceUri = new Uri(hostUri, servicePath);

var binding = new WebHttpBinding();

var client = new AuthenticationClient(binding, new EndpointAddress(serviceUri));

client.Endpoint.Behaviors.Add(new MyWebHttpBehaviour());

var credentials = new AccountCredentials
{
    Username = "myusername",
    Password = "mypassword"
};

var result = client.AuthenticateUser(credentials);      

(По какой-то причине WebHttpBehavior не реализует IEndpointBehavior, поэтому я создал свой собственный класс, который наследуется от WebHttpBehavior, а также реализует IEndpointBehavior).

Исключение, которое я получаю:

System.InvalidOperationException: если для транспорта включена ручная адресация, в каждом сообщении-запросе должен быть указан адрес назначения.

Может кто-нибудь помочь?

Ура, Энтони.

...