Självstudie: Självstudiekurs om Azure WCF Relay REST

Den här självstudien beskriver hur du skapar ett Azure Relay-värdprogram som exponerar ett REST-baserat gränssnitt. Med hjälp av REST kan du ge en webbklient, till exempel en webbläsare, åtkomst till API:er för Service Bus via HTTP-förfrågningar.

I självstudien används WINDOWS Communication Foundation (WCF) REST-programmeringsmodellen för att skapa en REST-tjänst på Azure Relay. Mer information finns i WCF REST Programming Model (WCF REST-programmeringsmodell ) och Designa och implementera tjänster.

Du utför följande uppgifter i den här självstudien:

  • Installera förutsättningar för den här självstudien.
  • Skapa ett Relay-namnområde.
  • Definiera ett REST-baserat WCF-tjänstkontrakt.
  • Implementera det REST-baserade WCF-kontraktet.
  • Var värd för och kör den REST-baserade WCF-tjänsten.
  • Kör och testa tjänsten.

Förutsättningar

För att slutföra den här självstudien, finns följande förhandskrav:

Skapa ett Relay-namnområde

För att komma igång med reläfunktionerna i Azure måste du först skapa ett namnområde för tjänsten. Ett namnområde tillhandahåller en omfångscontainer för adressering av Azure-resurser i ditt program. Följ anvisningarna här för att skapa ett Relay-namnområde.

Definiera ett REST-baserat WCF-tjänstkontrakt som ska användas med Azure Relay

När du skapar en WCF REST-tjänst måste du definiera kontraktet. Kontraktet anger vilka åtgärder som värden stöder. En tjänståtgärd liknar en webbtjänstmetod. Definiera ett kontrakt med ett C++-, C#- eller Visual Basic-gränssnitt. Varje metod i gränssnittet motsvarar en viss tjänsteåtgärd. Tillämpa attributet ServiceContractAttribute på varje gränssnitt och tillämpa attributet OperationContractAttribute på varje åtgärd.

Tips

Om en metod i ett gränssnitt som har ServiceContractAttribute inte har OperationContractAttribute exponeras inte den metoden. Koden som används för dessa uppgifter visas i exemplet som följer proceduren.

Den främsta skillnaden mellan ett WCF-kontrakt och ett REST-kontrakt är tillägget av en egenskap till OperationContractAttribute: WebGetAttribute. Den här egenskapen gör att du kan mappa en metod i gränssnittet till en metod på andra sidan av gränssnittet. I det här exemplet används attributet WebGetAttribute för att länka en metod till HTTP GET. Den här metoden gör att Service Bus kan hämta och tolka kommandon som skickas till gränssnittet korrekt.

Så här skapar du ett kontrakt med ett gränssnitt

  1. Starta Microsoft Visual Studio som administratör. Det gör du genom att högerklicka på Visual Studio-programikonen och välja Kör som administratör.

  2. I Visual Studio väljer du Skapa ett nytt projekt.

  3. I Skapa ett nytt projekt väljer du Konsolapp (.NET Framework) för C# och väljer Nästa.

  4. Ge projektet namnet ImageListener. Använd standardplatsen och välj sedan Skapa.

    För ett C#-projekt skapar Visual Studio en Program.cs-fil . Den här klassen innehåller en tom Main()-metod, ett krav för att ett konsolapprojekt ska kunna skapas på rätt sätt.

  5. Högerklicka på projektet ImageListener i Solution Explorer och välj sedan Hantera NuGet-paket.

  6. Välj Bläddra och sök sedan efter och välj WindowsAzure.ServiceBus. Välj Installera och godkänn användningsvillkoren.

    Det här steget lägger till referenser till Service Bus och System.ServiceModel.dll. Det här paketet lägger automatiskt till referenser till Service Bus-biblioteken och WCF System.ServiceModel.

  7. Lägg uttryckligen till en referens till System.ServiceModel.Web.dll projektet. Högerklicka på Referenser under projektmappen i Solution Explorer och välj Lägg till referens.

  8. I Lägg till referens väljer du Ramverk och anger System.ServiceModel.Web i Sök. Markera kryssrutan System.ServiceModel.Web och välj sedan OK.

Gör sedan följande kodändringar i projektet:

  1. Lägg till följande using -instruktioner överst i filen Program.cs .

    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Web;
    using System.IO;
    
    • System.ServiceModel är det namnområde som genom programmering ger åtkomst till grundläggande funktioner i WCF. WCF Relay använder många av objekten och attributen i WCF för att definiera tjänstkontrakt. Du använder det här namnområdet i de flesta av dina reläprogram.
    • System.ServiceModel.Channels hjälper dig att definiera kanalen, vilket är det objekt som du kommunicerar med Azure Relay och klientens webbläsare.
    • System.ServiceModel.Web innehåller de typer som gör att du kan skapa webbaserade program.
  2. Byt namn på ImageListener namnområdet till Microsoft.ServiceBus.Samples.

    namespace Microsoft.ServiceBus.Samples
    {
        ...
    
  3. Direkt efter inledande klammerparentes för namnområdesdeklarationen definierar du ett nytt gränssnitt med namnet IImageContract och tillämpar ServiceContractAttribute attributet på gränssnittet med värdet https://samples.microsoft.com/ServiceModel/Relay/RESTTutorial1.

    [ServiceContract(Name = "ImageContract", Namespace = "https://samples.microsoft.com/ServiceModel/Relay/RESTTutorial1")]
    public interface IImageContract
    {
    }
    

    Namnområdesvärdet skiljer sig från det namnområde som du använder under hela intervallet för din kod. Namnområdesvärdet är en unik identifierare för det här kontraktet och bör ha versionsinformation. Mer information finns i Versionhantering för tjänster. Genom att ange namnområdet uttryckligen förhindrar du att det förvalda namnområdesvärdet läggs till i kontraktnamnet.

  4. IImageContract I gränssnittet deklarerar du en metod för den enda åtgärd som IImageContract kontraktet exponerar i gränssnittet och tillämpar OperationContract attributet på den metod som du vill exponera som en del av det offentliga Service Bus-kontraktet.

    public interface IImageContract
    {
        [OperationContract]
        Stream GetImage();
    }
    
  5. OperationContract Lägg till värdet i -attributetWebGet.

    public interface IImageContract
    {
        [OperationContract, WebGet]
        Stream GetImage();
    }
    

    WebGet Genom att lägga till värdet kan relätjänsten dirigera HTTP GET-begäranden till GetImageoch översätta returvärdena GetImage för till ett HTTP GETRESPONSE svar. Senare i självstudien använder du en webbläsare för att komma åt den här metoden och för att visa bilden i webbläsaren.

  6. Direkt efter definitionen IImageContract deklarerar du en kanal som ärver från både IImageContract- och IClientChannel-gränssnittet.

    public interface IImageChannel : IImageContract, IClientChannel { }
    

    En kanal är det WCF-objekt via vilken tjänsten och klienten skickar information till varandra. Senare skapar du kanalen i värdprogrammet. Azure Relay använder sedan den här kanalen för att skicka HTTP GET-begäranden från webbläsaren till implementeringen GetImage . Reläet använder också kanalen för att ta GetImage returvärdet och översätta det till en HTTP GETRESPONSE för klientwebbläsaren.

  7. Välj Skapa>bygglösning för att bekräfta att ditt arbete är korrekt hittills.

Exempel som definierar ett WCF Relay-kontrakt

Följande kod visar ett grundläggande gränssnitt som definierar ett WCF Relay-kontrakt.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Web;
using System.IO;

namespace Microsoft.ServiceBus.Samples
{

    [ServiceContract(Name = "IImageContract", Namespace = "https://samples.microsoft.com/ServiceModel/Relay/")]
    public interface IImageContract
    {
        [OperationContract, WebGet]
        Stream GetImage();
    }

    public interface IImageChannel : IImageContract, IClientChannel { }

    class Program
    {
        static void Main(string[] args)
        {
        }
    }
}

Implementera det REST-baserade WCF-tjänstkontraktet

Om du vill skapa en WCF Relay-tjänst i REST-format skapar du först kontraktet med hjälp av ett gränssnitt. Nästa steg är att implementera gränssnittet. Den här proceduren omfattar att skapa en klass med namnet ImageService som implementerar det användardefinierade IImageContract gränssnittet. När du har implementerat kontraktet konfigurerar du sedan gränssnittet med hjälp av en App.config fil. Konfigurationsfilen innehåller nödvändig information för programmet. Den här informationen omfattar namnet på tjänsten, namnet på kontraktet och den typ av protokoll som används för att kommunicera med den vidarebefordrande tjänsten. Koden som används för dessa uppgifter visas i exemplet som följer proceduren.

Precis som i föregående steg är det liten skillnad mellan att implementera ett KONTRAKT i REST-format och ett WCF Relay-kontrakt.

Implementera ett Service Bus-kontrakt i REST-format

  1. Skapa en ny klass med namnet ImageService direkt efter definitionen av gränssnittet IImageContract. Klassen ImageService implementerar gränssnittet IImageContract.

    class ImageService : IImageContract
    {
    }
    

    Precis som med andra gränssnittsimplementeringar kan du implementera definitionen i en annan fil. Men i den här självstudiekursen visas implementeringen i samma fil som gränssnittsdefinitionen och Main()-metoden.

  2. Använd attributet ServiceBehaviorAttribute för IImageService klassen för att ange att klassen är en implementering av ett WCF-kontrakt.

    [ServiceBehavior(Name = "ImageService", Namespace = "https://samples.microsoft.com/ServiceModel/Relay/")]
    class ImageService : IImageContract
    {
    }
    

    Som tidigare nämnts är det här namnområdet inte ett traditionellt namnområde. Det är en del av WCF-arkitekturen som identifierar kontraktet. Mer information finns i Namn på datakontrakt.

  3. Lägg till en .jpg bild i projektet. Den här filen är en bild som tjänsten visar i den mottagande webbläsaren.

    1. Högerklicka på projektet och välj Lägg till.
    2. Välj sedan Befintligt objekt.
    3. Använd Lägg till befintligt objekt för att bläddra till en lämplig .jpg och välj sedan Lägg till. När du lägger till filen väljer du Alla filer i listrutan bredvid Filnamn.

    Resten av den här självstudien förutsätter att namnet på avbildningen är image.jpg. Om du har en annan fil måste du byta namn på avbildningen eller ändra koden för att kompensera.

  4. Kontrollera att den tjänst som körs kan hitta avbildningsfilen genom att högerklicka på bildfilen i Solution Explorer och sedan välja Egenskaper. I Egenskaper anger du Kopiera till Utdatakatalog till Kopiera om nyare.

  5. Använd proceduren i Skapa ett kontrakt med ett gränssnitt för att lägga till en referens till System.Drawing.dll sammansättning i projektet.

  6. Lägg till följande associerade using uttryck:

    using System.Drawing;
    using System.Drawing.Imaging;
    using Microsoft.ServiceBus;
    using Microsoft.ServiceBus.Web;
    
  7. ImageService I klassen lägger du till följande konstruktor som läser in bitmappen och förbereder för att skicka den till klientwebbläsaren:

    class ImageService : IImageContract
    {
        const string imageFileName = "image.jpg";
    
        Image bitmap;
    
        public ImageService()
        {
            this.bitmap = Image.FromFile(imageFileName);
        }
    }
    
  8. Direkt efter föregående kod lägger du till följande GetImage metod i ImageService klassen för att returnera ett HTTP-meddelande som innehåller avbildningen.

    public Stream GetImage()
    {
        MemoryStream stream = new MemoryStream();
        this.bitmap.Save(stream, ImageFormat.Jpeg);
    
        stream.Position = 0;
        WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg";
    
        return stream;
    }
    

    Den här implementeringen använder MemoryStream för att hämta avbildningen och förbereda den för direktuppspelning till webbläsaren. Den startar strömpositionen på noll, deklarerar dataströminnehållet som en .jpgoch strömmar informationen.

  9. Välj Skapa>bygglösning.

Definiera konfigurationen för att köra webbtjänsten på Service Bus

  1. Dubbelklicka på App.config i Solution Explorer för att öppna filen i Visual Studio-redigeraren.

    Den App.config filen innehåller tjänstnamn, slutpunkt och bindning. Slutpunkten är den plats som Azure Relay exponerar för klienter och värdar att kommunicera med varandra. Bindningen är den typ av protokoll som används för att kommunicera. Den största skillnaden här är att den konfigurerade tjänstslutpunkten refererar till en WebHttpRelayBinding-bindning .

  2. XML-elementet <system.serviceModel> är ett WCF-element som definierar en eller flera tjänster. Här används den för att definiera tjänstnamnet och slutpunkten. Lägg till ett <bindings> element som har följande innehåll längst ned i elementet<system.serviceModel>, men ändå inom <system.serviceModel>:

    <bindings>
        <!-- Application Binding -->
        <webHttpRelayBinding>
            <binding name="default">
                <security relayClientAuthenticationType="None" />
            </binding>
        </webHttpRelayBinding>
    </bindings>
    

    Det här innehållet definierar de bindningar som används i programmet. Du kan definiera flera bindningar, men för den här självstudien definierar du bara en.

    Den tidigare koden definierar en WCF Relay WebHttpRelayBinding-bindning med relayClientAuthenticationType inställd på None. Den här inställningen anger att en slutpunkt som använder den här bindningen inte kräver någon klientautentiseringsuppgift.

  3. Lägg till ett <services>-element efter elementet <bindings>. På ett liknande sätt som med bindningarna kan du definiera flera tjänster i en enda konfigurationsfil. I den här självstudiekursen kommer du dock bara att definiera en.

    <services>
        <!-- Application Service -->
        <service name="Microsoft.ServiceBus.Samples.ImageService"
             behaviorConfiguration="default">
            <endpoint name="RelayEndpoint"
                    contract="Microsoft.ServiceBus.Samples.IImageContract"
                    binding="webHttpRelayBinding"
                    bindingConfiguration="default"
                    behaviorConfiguration="sbTokenProvider"
                    address="" />
        </service>
    </services>
    

    Det här innehållet konfigurerar en tjänst som använder den tidigare definierade standardinställningen webHttpRelayBinding. Den använder också standardvärdet sbTokenProvider, som definieras i nästa steg.

  4. Efter elementet <services> skapar du ett <behaviors> element med följande innehåll och ersätter SAS_KEY med SAS-nyckeln (Signatur för delad åtkomst). Information om hur du hämtar en SAS-nyckel från Azure Portal finns i Hämta autentiseringsuppgifter för hantering.

    <behaviors>
        <endpointBehaviors>
            <behavior name="sbTokenProvider">
                <transportClientEndpointBehavior>
                    <tokenProvider>
                        <sharedAccessSignature keyName="RootManageSharedAccessKey" key="YOUR_SAS_KEY" />
                    </tokenProvider>
                </transportClientEndpointBehavior>
            </behavior>
            </endpointBehaviors>
            <serviceBehaviors>
                <behavior name="default">
                    <serviceDebug httpHelpPageEnabled="false" httpsHelpPageEnabled="false" />
                </behavior>
            </serviceBehaviors>
    </behaviors>
    
  5. I App.configersätter du hela anslutningssträngvärdet i <appSettings> -elementet med anslutningssträngen som du tidigare hämtade från portalen.

    <appSettings>
       <!-- Service Bus specific app settings for messaging connections -->
       <add key="Microsoft.ServiceBus.ConnectionString"
           value="Endpoint=sb://yourNamespace.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=YOUR_SAS_KEY"/>
    </appSettings>
    
  6. Välj Skapa>bygglösning för att skapa hela lösningen.

Exempel som implementerar det REST-baserade WCF-tjänstkontraktet

Följande kod visar kontraktet och tjänstimplementeringen för en REST-baserad tjänst som körs på Service Bus med bindningen WebHttpRelayBinding .

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Web;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Web;

namespace Microsoft.ServiceBus.Samples
{


    [ServiceContract(Name = "ImageContract", Namespace = "https://samples.microsoft.com/ServiceModel/Relay/")]
    public interface IImageContract
    {
        [OperationContract, WebGet]
        Stream GetImage();
    }

    public interface IImageChannel : IImageContract, IClientChannel { }

    [ServiceBehavior(Name = "ImageService", Namespace = "https://samples.microsoft.com/ServiceModel/Relay/")]
    class ImageService : IImageContract
    {
        const string imageFileName = "image.jpg";

        Image bitmap;

        public ImageService()
        {
            this.bitmap = Image.FromFile(imageFileName);
        }

        public Stream GetImage()
        {
            MemoryStream stream = new MemoryStream();
            this.bitmap.Save(stream, ImageFormat.Jpeg);

            stream.Position = 0;
            WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg";

            return stream;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
        }
    }
}

I följande exempel visas den App.config fil som är associerad med tjänsten.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/>
    </startup>
    <system.serviceModel>
        <extensions>
            <!-- In this extension section we are introducing all known service bus extensions. User can remove the ones they don't need. -->
            <behaviorExtensions>
                <add name="connectionStatusBehavior"
                    type="Microsoft.ServiceBus.Configuration.ConnectionStatusElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add name="transportClientEndpointBehavior"
                    type="Microsoft.ServiceBus.Configuration.TransportClientEndpointBehaviorElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add name="serviceRegistrySettings"
                    type="Microsoft.ServiceBus.Configuration.ServiceRegistrySettingsElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
            </behaviorExtensions>
            <bindingElementExtensions>
                <add name="netMessagingTransport"
                    type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingTransportExtensionElement, Microsoft.ServiceBus,  Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add name="tcpRelayTransport"
                    type="Microsoft.ServiceBus.Configuration.TcpRelayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add name="httpRelayTransport"
                    type="Microsoft.ServiceBus.Configuration.HttpRelayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add name="httpsRelayTransport"
                    type="Microsoft.ServiceBus.Configuration.HttpsRelayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add name="onewayRelayTransport"
                    type="Microsoft.ServiceBus.Configuration.RelayedOnewayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
            </bindingElementExtensions>
            <bindingExtensions>
                <add name="basicHttpRelayBinding"
                    type="Microsoft.ServiceBus.Configuration.BasicHttpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add name="webHttpRelayBinding"
                    type="Microsoft.ServiceBus.Configuration.WebHttpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add name="ws2007HttpRelayBinding"
                    type="Microsoft.ServiceBus.Configuration.WS2007HttpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add name="netTcpRelayBinding"
                    type="Microsoft.ServiceBus.Configuration.NetTcpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add name="netOnewayRelayBinding"
                    type="Microsoft.ServiceBus.Configuration.NetOnewayRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add name="netEventRelayBinding"
                    type="Microsoft.ServiceBus.Configuration.NetEventRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add name="netMessagingBinding"
                    type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
            </bindingExtensions>
        </extensions>
      <bindings>
        <!-- Application Binding -->
        <webHttpRelayBinding>
          <binding name="default">
            <security relayClientAuthenticationType="None" />
          </binding>
        </webHttpRelayBinding>
      </bindings>
      <services>
        <!-- Application Service -->
        <service name="Microsoft.ServiceBus.Samples.ImageService"
             behaviorConfiguration="default">
          <endpoint name="RelayEndpoint"
                  contract="Microsoft.ServiceBus.Samples.IImageContract"
                  binding="webHttpRelayBinding"
                  bindingConfiguration="default"
                  behaviorConfiguration="sbTokenProvider"
                  address="" />
        </service>
      </services>
      <behaviors>
        <endpointBehaviors>
          <behavior name="sbTokenProvider">
            <transportClientEndpointBehavior>
              <tokenProvider>
                <sharedAccessSignature keyName="RootManageSharedAccessKey" key="YOUR_SAS_KEY" />
              </tokenProvider>
            </transportClientEndpointBehavior>
          </behavior>
        </endpointBehaviors>
        <serviceBehaviors>
          <behavior name="default">
            <serviceDebug httpHelpPageEnabled="false" httpsHelpPageEnabled="false" />
          </behavior>
        </serviceBehaviors>
      </behaviors>
    </system.serviceModel>
    <appSettings>
        <!-- Service Bus specific app settings for messaging connections -->
        <add key="Microsoft.ServiceBus.ConnectionString"
            value="Endpoint=sb://yourNamespace.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=YOUR_SAS_KEY>"/>
    </appSettings>
</configuration>

Vara värd för DEN REST-baserade WCF-tjänsten för att använda Azure Relay

I det här avsnittet beskrivs hur du kör en webbtjänst med hjälp av ett konsolprogram med WCF Relay. En fullständig lista över koden som skrivits i det här avsnittet visas i exemplet som följer proceduren.

Så här skapar du en basadress för tjänsten

  1. I funktionsdeklarationen Main() skapar du en variabel för att lagra projektets namnområde. Ersätt yourNamespace med namnet på det Relay-namnområde som du skapade tidigare.

    string serviceNamespace = "yourNamespace";
    

    Service Bus använder namnet på ditt namnområde för att skapa ett unikt URI.

  2. Skapa en Uri-instans för tjänstens basadress som baseras på namnområdet.

    Uri address = ServiceBusEnvironment.CreateServiceUri("https", serviceNamespace, "Image");
    

Så här skapar och konfigurerar du webbtjänstevärden

Fortfarande i Main()skapar du webbtjänstvärden med hjälp av den URI-adress som skapades tidigare i det här avsnittet.

WebServiceHost host = new WebServiceHost(typeof(ImageService), address);

Tjänstevärden är det WCF-objekt som instantierar värdprogrammet. I det här exemplet skickas den typ av värd som du vill skapa, vilket är en ImageService, och även den adress där du vill exponera värdprogrammet.

Så här kör du webbtjänstevärden

  1. Fortfarande i Main()lägger du till följande rad för att öppna tjänsten.

    host.Open();
    

    Tjänsten körs nu.

  2. Visa ett meddelande som anger att tjänsten körs och hur du stoppar tjänsten.

    Console.WriteLine("Copy the following address into a browser to see the image: ");
    Console.WriteLine(address + "GetImage");
    Console.WriteLine();
    Console.WriteLine("Press [Enter] to exit");
    Console.ReadLine();
    
  3. Stäng tjänstevärden när du är klar.

    host.Close();
    

Exempel på tjänstkontraktet och implementeringen

Följande exempel innehåller tjänstekontraktet och implementeringen från föregående steg i självstudiekursen och fungerar som värd för tjänsten i ett konsolprogram. Kompilera följande kod till en körbar fil med namnet ImageListener.exe.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Web;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Web;

namespace Microsoft.ServiceBus.Samples
{

    [ServiceContract(Name = "ImageContract", Namespace = "https://samples.microsoft.com/ServiceModel/Relay/")]
    public interface IImageContract
    {
        [OperationContract, WebGet]
        Stream GetImage();
    }

    public interface IImageChannel : IImageContract, IClientChannel { }

    [ServiceBehavior(Name = "ImageService", Namespace = "https://samples.microsoft.com/ServiceModel/Relay/")]
    class ImageService : IImageContract
    {
        const string imageFileName = "image.jpg";

        Image bitmap;

        public ImageService()
        {
            this.bitmap = Image.FromFile(imageFileName);
        }

        public Stream GetImage()
        {
            MemoryStream stream = new MemoryStream();
            this.bitmap.Save(stream, ImageFormat.Jpeg);

            stream.Position = 0;
            WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg";

            return stream;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            string serviceNamespace = "InsertServiceNamespaceHere";
            Uri address = ServiceBusEnvironment.CreateServiceUri("https", serviceNamespace, "Image");

            WebServiceHost host = new WebServiceHost(typeof(ImageService), address);
            host.Open();

            Console.WriteLine("Copy the following address into a browser to see the image: ");
            Console.WriteLine(address + "GetImage");
            Console.WriteLine();
            Console.WriteLine("Press [Enter] to exit");
            Console.ReadLine();

            host.Close();
        }
    }
}

Köra och testa tjänsten

Gör följande för att köra appen när du har skapat lösningen:

  1. Välj F5 eller bläddra till den körbara filplatsen ImageListener\bin\Debug\ImageListener.exeför att köra tjänsten. Håll appen igång eftersom den krävs för nästa steg.
  2. Kopiera och klistra in adressen från kommandotolken i en webbläsare för att se bilden.
  3. När du är klar väljer du Retur i kommandotolken för att stänga appen.

Nästa steg

Nu när du har skapat ett program som använder Azure Relay-tjänsten kan du läsa följande artiklar om du vill veta mer: