Comment : utiliser le transport HTTP

Mise à jour : novembre 2007

Vous pouvez utiliser le transport HTTP pour créer des applications sur un appareil qui se connectera à un service Windows Communication Foundation (WCF) sur l'ordinateur.

Cette rubrique décrit comment configurer le service WCF pour gérer la connexion d'appareils et comment créer l'application cliente. Elle explique les différences de configuration de service WCF et de codage côté client dont il faut tenir compte pour permettre aux appareils mobiles de se connecter au service. Pour plus d'informations sur la création d'applications WCG pour l'ordinateur, consultez Didacticiel de mise en route dans la documentation WCF.

Pour créer le service WCF pour l'ordinateur

  1. Créez un projet de service Web.

  2. Modifiez le fichier Web.config comme indiqué dans l'exemple suivant. Modifiez les éléments et attributs suivants dans le fichier :

    • Remplacez la valeur de l'attribut binding de <endpoint> par « basicHttpBinding ». Le .NET Compact Framework prend en charge le codage de texte, mais pas le codage binaire.

    • Modifiez l'attribut behaviorConfiguration pour faire référence au nouveau nom de comportement.

    • Remplacez l'élément <behavior> comme indiqué dans l'exemple.

    • Si vous devez enregistrer le gestionnaire de service HTTP dans le fichier Web.config, ajoutez un nouvel élément <system.WebServer> avec les informations fournies dans l'exemple.

    <?xml version="1.0"?>
    
    <configuration xmlns="https://schemas.microsoft.com/.NetConfiguration/v2.0">
      <system.serviceModel>
        <services>
          <service name="CalculatorService" behaviorConfiguration="MyServiceTypeBehaviors">
            <endpoint contract="ICalculatorService" binding="basicHttpBinding"/>
          </service>
        </services>
        <behaviors>
          <serviceBehaviors>
            <behavior name="MyServiceTypeBehaviors">
              <serviceMetadata httpGetEnabled="true" />
              <serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>
    
      <system.web>
        <compilation debug="true"/>
      </system.web>
    
      <system.webServer>
        <handlers>
          <add name="HttpSvcHandler" path="*.svc" verb="*" type="System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" resourceType="Unspecified" />
        </handlers>
      </system.webServer>
    
    </configuration>
    
  3. Dans le code source du service WCF, supprimez tous les paramètres spécifiés dans les attributs ServiceContract et OperationContract.

    Remarque :

    Cet exemple n'implémente pas la prise en charge des paramètres spécifiés dans les contrats, tels que ServiceContract et OperationContract. Si vous voulez utiliser la prise en charge des paramètres pour ces contrats, vous pouvez faire appel à l'outil ServiceModel Utility (NetCFSvcUtil.exe) WCF du .NET Compact Framework pour générer le code client. Cet outil intègre la prise en charge de ces paramètres dans des applications basées sur le .NET Compact Framework. NetCFSvcUtil.exe est disponible dans les Power Toys pour le .NET Compact Framework. Pour plus d'informations, consultez Power Toys pour le .NET Compact Framework (en anglais).

    L'exemple suivant affiche le code source du service WCF pour une application de calculatrice simplifiée.

    <ServiceContract()>  _
    Public Interface ICalculatorService
        <OperationContract()>  _
        Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double 
        '<OperationContract()>  _
        Function Subtract(ByVal n1 As Double, ByVal n2 As Double) As Double
    End Interface
    
    
    Public Class CalculatorService
        Implements ICalculatorService
    
        Public Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculatorService.Add
            Return n1 + n2
    
        End Function
    
        Public Function Subtract(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculatorService.Subtract
            Return n1 - n2
    
        End Function
    End Class
    
    [ServiceContract()]
    public interface ICalculatorService
    {
        [OperationContract]
        double Add(double n1, double n2);
        [OperationContract]
        double Subtract(double n1, double n2);
    }
    
    public class CalculatorService : ICalculatorService
    {
        public double Add(double n1, double n2) { return n1 + n2; }
        public double Subtract(double n1, double n2) { return n1 - n2; }
    }
    
  4. Affectez au service WCF un port spécifique sur votre serveur Web.

    Utilisez un numéro de port compris entre 10000 et 650000. Cet exemple utilise le port 50505.

  5. Démarrez le serveur Web.

    Si vous souhaitez consulter la sortie Web Services Description Language (WSDL) et exécuter le service sur le localhost, accédez à https://localhost:50505/CalculatorService/Service .svc? wsdl. Utilisez les mêmes numéro de port et nom de projet Web que ceux du service WCF.

  6. Si vous comptez vous connecter au serveur Web à partir d'un ordinateur ou périphérique distant, installez un répertoire virtuel qui pointe vers le répertoire contenant le projet Web.

    Remarque :

    Le serveur de développement ASP.NET dans Visual Studio répond uniquement aux demandes de votre ordinateur de développement local. Nous vous recommandons d'utiliser les services IIS (Internet Information Services) pour spécifier un répertoire virtuel. Vous pourrez alors vous connecter au serveur Web d'un périphérique distant si le serveur est accessible.

  7. Vérifiez que vous pouvez accéder au répertoire à partir d'un navigateur d'ordinateur de bureau et d'un navigateur d'appareil.

Pour créer le client .NET Compact Framework

  1. Lorsque le service est en cours d'exécution, ouvrez une ligne de commande et accédez au répertoire contenant le service WCF.

  2. À partir de la ligne de commande, exécutez l'outil WCF ServiceModel Desktop Utility (Svcutil.exe) pour générer un proxy client WCF. L'exemple suivant illustre l'appel de ligne de commande de SvcUtil dans lequel le service est hébergé sur le localhost :

    svcutil.exe /language:c# https://localhost:50505/CalculatorService/Service.svc
    

    L'exemple suivant affiche un proxy client généré par SvcUtil qui est basé sur l'exemple de calculatrice simple.

    //------------------------------------------------------------------------------
    // <auto-generated>
    //     This code was generated by a tool.
    //     Runtime Version:2.0.50727.42
    //
    //     Changes to this file may cause incorrect behavior and will be lost if
    //     the code is regenerated.
    // </auto-generated>
    //------------------------------------------------------------------------------
    
    
    
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
    [System.ServiceModel.ServiceContractAttribute(ConfigurationName="ICalculatorService")]
    public interface ICalculatorService
    {
    
        [System.ServiceModel.OperationContractAttribute(Action="https://fabrikam.com/ICalculatorService/Add", ReplyAction="https://fabrikam.com/ICalculatorService/AddResponse")]
        double Add(double n1, double n2);
    
        [System.ServiceModel.OperationContractAttribute(Action="https://fabrikam.com/ICalculatorService/Subtract", ReplyAction="https://fabrikam.com/ICalculatorService/SubtractResponse")]
        double Subtract(double n1, double n2);
    }
    
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
    public interface ICalculatorServiceChannel : ICalculatorService, System.ServiceModel.IClientChannel
    {
    }
    
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
    public partial class CalculatorServiceClient : System.ServiceModel.ClientBase<ICalculatorService>, ICalculatorService
    {
    
        public CalculatorServiceClient()
        {
        }
    
        public CalculatorServiceClient(string endpointConfigurationName) : 
                base(endpointConfigurationName)
        {
        }
    
        public CalculatorServiceClient(string endpointConfigurationName, string remoteAddress) : 
                base(endpointConfigurationName, remoteAddress)
        {
        }
    
        public CalculatorServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : 
                base(endpointConfigurationName, remoteAddress)
        {
        }
    
        public CalculatorServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : 
                base(binding, remoteAddress)
        {
        }
    
        public double Add(double n1, double n2)
        {
            return base.Channel.Add(n1, n2);
        }
    
        public double Subtract(double n1, double n2)
        {
            return base.Channel.Subtract(n1, n2);
        }
    }
    
  3. Supprimez les attributs et éléments non pris en charge du code proxy client généré, y compris les suivants :

    • tous les attributs System.ServiceModel ;

    • les références à la classe IClientChannel ;

    • les références aux noms de configuration du <endpoint> ;

    • les implémentations de méthode qui appellent des méthodes de l'interface ServiceContract sur le canal interne.

    L'exemple suivant affiche le code une fois ces modifications appliquées.

    '------------------------------------------------------------------------------
    ' <auto-generated>
    '     This code was generated by a tool.
    '     Runtime Version:2.0.50727.312
    '
    '     Changes to this file may cause incorrect behavior and will be lost if
    '     the code is regenerated.
    ' </auto-generated>
    '------------------------------------------------------------------------------
    
    Option Strict Off
    Option Explicit On
    
    
    
    Public Interface ICalculatorService
    
        Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double
    
        Function Subtract(ByVal n1 As Double, ByVal n2 As Double) As Double
    End Interface
    
    Partial Public Class CalculatorServiceClient
        Inherits System.ServiceModel.ClientBase(Of ICalculatorService)
        Implements ICalculatorService
    
        ' Add a variable containing the endpoint address.
        Public Shared ServiceEndPoint As New System.ServiceModel.EndpointAddress("https://fabrikam.com/CalcService/CalculatorService/Service.svc")
    
        Public Sub New(ByVal binding As System.ServiceModel.Channels.Binding, ByVal remoteAddress As System.ServiceModel.EndpointAddress)
            MyBase.New(binding, remoteAddress)
        End Sub
    
        Public Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculatorService.Add
            Return MyBase.Channel.Add(n1, n2)
        End Function
    
        Public Function Subtract(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculatorService.Subtract
            Return MyBase.Channel.Subtract(n1, n2)
        End Function
    End Class
    
    //------------------------------------------------------------------------------
    // <auto-generated>
    //     This code was generated by a tool.
    //     Runtime Version:2.0.50727.42
    //
    //     Changes to this file may cause incorrect behavior and will be lost if
    //     the code is regenerated.
    // </auto-generated>
    //------------------------------------------------------------------------------
    
    
    public interface ICalculatorService
    {
    
        double Add(double n1, double n2);
    
        double Subtract(double n1, double n2);
    }
    
    public partial class CalculatorServiceClient : System.ServiceModel.ClientBase<ICalculatorService>, ICalculatorService
    {
    
        // Add a variable to specify the server address.
        public static System.ServiceModel.EndpointAddress ServiceEndPoint = new System.ServiceModel.EndpointAddress("https://fabrikam.com/CalcService/CalculatorService/Service.svc");
    
        public CalculatorServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : 
                base(binding, remoteAddress)
        {
        }
    
        public double Add(double n1, double n2)
        {
            return base.Channel.Add(n1, n2);
        }
    
        public double Subtract(double n1, double n2)
        {
            return base.Channel.Subtract(n1, n2);
        }
    }
    
  4. Créez un projet client.

  5. Ajoutez le proxy client généré au projet.

  6. Dans le code proxy généré, remplacez la référence qualifiée complète à ClientBase<TChannel> par la classe ClientBase définie par l'utilisateur.

  7. Dans le code proxy généré, ajoutez des implémentations de méthode en appelant la méthode Call dans la classe ClientBase définie par l'utilisateur.

    Public Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculatorService.Add
        Return System.Convert.ToDouble(MyBase.Call("Add", "https://fabrikam.com/CalcService/ICalculatorService/Add", New String() {"n1", "n2"}, New Object() {n1, n2}, GetType(Double)))
    End Function
    
    public double Add(double n1, double n2)
    {
        return (double)base.Call("Add", "https://fabrikam.com/CalcService/ICalculatorService/Add", new string[] { "n1", "n2" }, new object[] { n1, n2 }, typeof(double));
    }
    
  8. Ajoutez au projet la classe de base pour le proxy. Cette classe s'appelle ClientBase.

    Modifiez la référence de classe de base de votre proxy client en la faisant pointer vers votre implémentation de ClientBase.

    Remarque :

    Dans cet exemple, la classe CustomBodyWriter dans ClientBase ne prend en charge que les types primitifs. Pour prendre en charge des types non primitifs, vous devez étendre la méthode OnWriteBodyContents. Par exemple, vous pouvez appeler un sérialiseur personnalisé pour sérialiser des données de message. Dans ce cas, vous convertissez des attributs de code dans le proxy client généré en attributs que le sérialiseur XML pourrait consommer. Dans ce scénario, vous devez commencer par ajouter le commutateur suivant lorsque vous exécutez SvcUtil : /serializer:xmlserializer http://point de terminaison.

    Le code suivant illustre un exemple de la classe ClientBase.

    Public Class ClientBase(Of TChannel As Class)
    
        Private requestChannel As IRequestChannel
        Private messageVersion As MessageVersion
    
    
        Public Sub New(ByVal binding As System.ServiceModel.Channels.Binding, ByVal remoteAddress As System.ServiceModel.EndpointAddress)
            'this.remoteAddress = remoteAddress;
            Me.messageVersion = binding.MessageVersion
    
            Dim channelFactory As IChannelFactory(Of IRequestChannel)
            channelFactory = binding.BuildChannelFactory(Of IRequestChannel)(New BindingParameterCollection())
            channelFactory.Open()
            Me.requestChannel = channelFactory.CreateChannel(remoteAddress)
    
        End Sub
    
    
        Public Function [Call](ByVal op As String, ByVal action As String, ByVal varnames() As String, ByVal varvals() As Object, ByVal returntype As Type) As Object
            requestChannel.Open(TimeSpan.MaxValue)
    
            Dim msg As Message = Message.CreateMessage(Me.messageVersion, action, New CustomBodyWriter(op, varnames, varvals, "<ns passed in from Proxy>"))
    
            Dim reply As Message = requestChannel.Request(msg, TimeSpan.MaxValue)
            Dim reader As XmlDictionaryReader = reply.GetReaderAtBodyContents()
            reader.ReadToFollowing(op + "Result")
            Return reader.ReadElementContentAs(returntype, Nothing)
    
        End Function
    End Class
    
    
    Friend Class CustomBodyWriter
        Inherits BodyWriter
        Private op As String
        Private varnames() As String
        Private varvals() As Object
        Private ns As String
    
    
        Public Sub New(ByVal op As String, ByVal varnames() As String, ByVal varvals() As Object, ByVal ns As String)
            MyBase.New(True)
            Me.op = op
            Me.varnames = varnames
            Me.varvals = varvals
            Me.ns = ns
    
        End Sub
    
    
        Protected Overrides Sub OnWriteBodyContents(ByVal writer As XmlDictionaryWriter)
            writer.WriteStartElement(op, ns)
            Dim i As Integer
            For i = 0 To varnames.Length
                writer.WriteElementString(varnames(i), varvals(i).ToString())
            Next i
            writer.WriteEndElement()
    
        End Sub
    End Class
    
    public class ClientBase<TChannel>
        where TChannel : class
    {
        private IRequestChannel requestChannel;
        private MessageVersion messageVersion;
    
        public ClientBase(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress)
        {
            //this.remoteAddress = remoteAddress;
            this.messageVersion = binding.MessageVersion;
    
            IChannelFactory<IRequestChannel> channelFactory = binding.BuildChannelFactory<IRequestChannel>(
                new BindingParameterCollection());
            channelFactory.Open();
            this.requestChannel = channelFactory.CreateChannel(remoteAddress);
        }
    
        public object Call(string op, string action, string[] varnames, object[] varvals, Type returntype)
        {
            requestChannel.Open(TimeSpan.MaxValue);
    
            //Message msg =                     
            //Message.CreateMessage(MessageVersion.<FromBinding>,
            //      action,
            //      new CustomBodyWriter(op, varnames, varvals,                 
            //"<ns passed in from Proxy>"));
    
            Message msg =                   
            Message.CreateMessage(this.messageVersion, action,
                  new CustomBodyWriter(op, varnames, varvals,               
            "<ns passed in from Proxy>"));
    
            Message reply = requestChannel.Request(msg, TimeSpan.MaxValue);
            XmlDictionaryReader reader = reply.GetReaderAtBodyContents();
            reader.ReadToFollowing(op + "Result");
            return reader.ReadElementContentAs(returntype, null);
        }
    
    }
    
    internal class CustomBodyWriter : BodyWriter
    {
        private string op;
        private string[] varnames;
        private object[] varvals;
        private string ns;
    
        public CustomBodyWriter(string op, string[] varnames, object[] varvals, string ns)
            : base(true)
        {
            this.op = op;
            this.varnames = varnames;
            this.varvals = varvals;
            this.ns = ns;
        }
    
        protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
        {
            writer.WriteStartElement(op, ns);
            for (int i = 0; i < varnames.Length; i++)
                writer.WriteElementString(varnames[i], varvals[i].ToString());
            writer.WriteEndElement();
        }
    }
    
  9. Ajoutez une classe à instancier et utilisez le proxy client.

    L'exemple suivant affiche un code qui appelle le proxy client.

    Shared Sub Main(ByVal args() As String)
        Dim serverAddress As String = CalculatorServiceClient.ServiceEndPoint.Uri.AbsoluteUri
        ' Using basic http connection. WS binding should be also available.
        Dim proxy As ICalculatorService = New CalculatorServiceClient(New BasicHttpBinding, New EndpointAddress(serverAddress))
        MessageBox.Show("Add 3 + 6...")
        MessageBox.Show(proxy.Add(3, 6).ToString)
        MessageBox.Show("Subtract 8 - 3...")
        MessageBox.Show(proxy.Subtract(8, 3).ToString)
    End Sub
    
    static void Main()
    {
        string serverAddress = CalculatorServiceClient.ServiceEndPoint.Uri.AbsoluteUri;
        // Using basic http connection. WS binding should be also available.
        ICalculatorService proxy = new CalculatorServiceClient(new BasicHttpBinding(), new EndpointAddress(serverAddress));
    
    
        MessageBox.Show("Add 3 + 6...");
        MessageBox.Show((proxy.Add(3, 6)).ToString());
        MessageBox.Show("Subtract 8 - 3...");        
        MessageBox.Show((proxy.Subtract(8, 3)).ToString());
    
    }
    
  10. Générez l'application cliente et déployez-la sur votre appareil.

  11. Lorsque le service WCF est en cours d'exécution et que votre appareil est connecté au réseau, démarrez l'application cliente sur l'appareil.

Compilation du code

Le code source pour le service WCF requiert des références aux espaces de noms suivants :

Le code source pour la classe ClientBase requiert des références aux espaces de noms suivants :

Le code source pour la classe qui contient la méthode Main dans l'application cliente requiert des références aux espaces de noms suivants :

Sécurité

Cet exemple n'implémente aucune fonctionnalité de sécurité WCF. Pour plus d'informations sur les fonctionnalités de sécurité prises en charge, consultez Messagerie dans le .NET Compact Framework.

Voir aussi

Concepts

Messagerie dans le .NET Compact Framework

Autres ressources

Développement Windows Communication Foundation (WCF) et le .NET Compact Framework