Я пытаюсь получить доступ к службам 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: если для транспорта включена ручная адресация, в каждом сообщении-запросе должен быть указан адрес назначения.
Может кто-нибудь помочь?
Ура,
Энтони.