[Azure] Silverlight 3 & .NET Services
Comme expliqué dans mon article sur Azure, .NET Services permet de faire abstraction de tous les problèmes de firewall/dmz et autre joyeusetés !
Il se trouve que la consommation de service WCF “on the cloud” grâce à .NET Services fonctionne correctement excepté en Silverlight ou j’ai eu quelques petits problèmes.
Voici comment faire communiquer un service (Service echo du SDK) WCF utilisant .NET Services et Silverlight 2/3.
Télécharger la source de ce poste ici.
Le contrat contient une simple méthode Echo qui retourne ce qu’on lui passe en paramêtre.
[ServiceContract(Name = "IEchoContract", Namespace = "http://samples.microsoft.com/ServiceModel/Relay/")]
public interface IEchoContract
{
[OperationContract]
string Echo(string text);
}
public interface IEchoChannel : IEchoContract, IClientChannel { }
- Création d’un second contrat permettant d’exposer le clientaccesspolicy.xml
[ServiceContract]
public interface IPolicyRetriever
{
[OperationContract, WebGet(UriTemplate = "/clientaccesspolicy.xml")]
Stream GetSilverlightPolicy();
}
- Implémentation des deux contrats
[ServiceBehavior(Name = "EchoService", Namespace = "http://samples.microsoft.com/ServiceModel/Relay/")]
class EchoService : IEchoContract, IPolicyRetriever
{
public string Echo(string text)
{
Console.WriteLine("Echoing: {0}", text);
return text;
}
#region IEchoContract Members
#endregion
Stream StringToStream(string result)
{
WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
return new MemoryStream(Encoding.UTF8.GetBytes(result));
}
public Stream GetSilverlightPolicy()
{
string result = @"<?xml version=""1.0"" encoding=""utf-8""?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers=""*"">
<domain uri=""*""/>
</allow-from>
<grant-to>
<resource path=""/"" include-subpaths=""true""/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>";
return StringToStream(result);
}
}
- Hébergement de votre service (n’oubliez pas d’inclure le SDK Helper)
ServiceBusEnvironment.SystemConnectivity.Mode = GetConnectivityMode(args);
string solutionName = "juliendblog";
string solutionPassword = "mdp";
Uri address = ServiceBusEnvironment.CreateServiceUri("http", solutionName, "EchoService");
TransportClientEndpointBehavior userNamePasswordServiceBusCredential = new TransportClientEndpointBehavior();
userNamePasswordServiceBusCredential.CredentialType = TransportClientCredentialType.UserNamePassword;
userNamePasswordServiceBusCredential.Credentials.UserName.UserName = solutionName;
userNamePasswordServiceBusCredential.Credentials.UserName.Password = solutionPassword;
ServiceHost host = new ServiceHost(typeof(EchoService));
foreach (ServiceEndpoint endpoint in host.Description.Endpoints)
endpoint.Behaviors.Add(userNamePasswordServiceBusCredential);
host.Open();
Console.WriteLine("Service address: " + address);
Console.WriteLine("Press [Enter] to exit");
Console.ReadLine();
host.Close();
- Désactivation des credentials car Silverlight ne les supporte pas
On le fait à la fois pour basicHttpRelayBinding pour que Silverlight le consomme mais aussi avec webHttpRelayBinding afin d’exposer le clientaccesspolicy
<bindings>
<basicHttpRelayBinding>
<binding name="default">
<security mode="None" relayClientAuthenticationType="None"/>
</binding>
</basicHttpRelayBinding>
<webHttpRelayBinding>
<binding name="default2">
<security relayClientAuthenticationType="None"/>
</binding>
</webHttpRelayBinding>
</bindings>
<service name="Microsoft.ServiceBus.Samples.EchoService" behaviorConfiguration="Metadata">
<host>
<baseAddresses>
<add baseAddress="http://juliendblog.servicebus.windows.net"/>
</baseAddresses>
</host>
<endpoint contract="Microsoft.ServiceBus.Samples.IEchoContract" address="EchoService"
binding="basicHttpRelayBinding" bindingConfiguration="default" />
<endpoint address=""
binding="webHttpRelayBinding"
contract="Microsoft.ServiceBus.Samples.IPolicyRetriever"
bindingConfiguration="default2" behaviorConfiguration="webHttpBehaviour" />
</service>
- Ajout d’un behavior (mettre votre adresse locale) afin de pouvoir générer le proxy Silverlight (merci à maxime boennec pour le tuyaux)
<behaviors>
<serviceBehaviors>
<behavior name="Metadata">
<serviceMetadata httpGetEnabled="true" httpGetUrl="http://Julien-PC:1234/ServiceMeta" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="webHttpBehaviour">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
- Puis consommation du service en Silverlight (Add service reference sur l’adresse locale décrite dans le serviceMedata)