Step 2: Define a REST-based WCF Service Contract to use with Service Bus

Important

This tutorial is moving to a new location, and this version will soon be retired. You can view the most recent version here: https://azure.microsoft.com/en-us/documentation/articles/service-bus-relay-rest-tutorial/.

This is the second of four tasks required to create a basic REST-style service for Service Bus. For an overview of all four tasks, see the Service Bus REST Tutorial.

As with other Service Bus services, when you create a REST-style service, you must define the contract. The contract specifies what operations the host supports. A service operation can be thought of as a web service method. Contracts are created by defining a C++, C#, or Visual Basic interface. Each method in the interface corresponds to a specific service operation. The ServiceContractAttribute attribute must be applied to each interface, and the OperationContractAttribute attribute must be applied to each operation. If a method in an interface that has the ServiceContractAttribute does not have the OperationContractAttribute, that method is not exposed. The code used for these tasks is shown in the example following the procedure.

The primary difference between a basic Service Bus contract and a REST-style contract is the addition of a property to the OperationContractAttribute: WebGetAttribute. This property lets you map a method in your interface to a method on the other side of the interface. In this case, we will use WebGetAttribute to link a method to HTTP GET. This allows Service Bus to accurately retrieve and interpret commands sent to the interface.

Expected time to completion: 10 minutes.

To create a Service Bus contract with an interface

  1. Open Visual Studio as an administrator by right-clicking the program in the Start menu and selecting Run as administrator.

  2. Create a new console application project. Click the File menu and select New, Project. In the New Project dialog, select Visual C# (if Visual C# does not appear, look under Other Languages), select the Console Application template, and name it ImageListener. Use the default Location. Click OK to create the project.

  3. For a C# project, Visual Studio creates a file that is named Program.cs. This class will contain an empty method called Main().This method is required for a console application project to build correctly. Therefore, you can safely leave it in the project.

  4. Add a reference to System.ServiceModel.dll to the project:

    1. In the Solution Explorer, right-click the References folder under the project folder and then click Add Reference.

    2. Select the .NET tab in the Add Reference dialog and scroll down until you see System.ServiceModel, select it. Then click OK.

  5. Repeat the previous step to add a reference to the System.ServiceModel.Web.dll assembly.

  6. Add a using statement for the System.ServiceModel, System.ServiceModel.Channels, System.ServiceModel.Web, and System.IO namespaces.

    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Web;
    using System.IO;
    

    System.ServiceModel is the namespace that lets you programmatically access the basic features of the Windows Communication Foundation (WCF). Service Bus uses many of the objects and attributes of WCF to define service contracts. You will use this namespace in most of your Service Bus applications. Similarly, System.ServiceModel.Channels helps define the channel, which is the object through which you communicate with the Service Bus and the client web browser. Finally, System.ServiceModel.Web contains the types that let you create web-based applications.

  7. Rename the namespace for the program from the Visual Studio default to Microsoft.ServiceBus.Samples.

    namespace Microsoft.ServiceBus.Samples
    {
    ...
    
  8. Directly after the namespace declaration, define a new interface named IImageContract and apply the ServiceContractAttribute attribute to the interface with a value of https://samples.microsoft.com/ServiceModel/Relay/. The namespace value differs from the namespace that you use throughout the scope of your code. The namespace value is used as a unique identifier for this contract, and should have versioning information. For more information, see, see Service Versioning. Specifying the namespace explicitly prevents the default namespace value from being added to the contract name.

    [ServiceContract(Name = "ImageContract", Namespace = "https://samples.microsoft.com/ServiceModel/Relay/RESTTutorial1")]
    public interface IImageContract
    {
    }
    
  9. Within the IImageContract interface, declare a method for the single operation the IImageContract contract exposes in the interface and apply the OperationContractAttribute attribute to the method that you want to expose as part of the public Service Bus contract.

    public interface IImageContract
    {
        [OperationContract]
        Stream GetImage();
    }
    
  10. Next to the OperationContract attribute, apply the WebGet attribute.

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

    Doing so enables Service Bus to route HTTP GET requests to GetImage, and to translate the return values of GetImage into an HTTP GETRESPONSE reply. Later in the tutorial, you will use a web browser to access this method, and to display the image in the browser.

  11. Directly underneath the IImageContract definition, declare a channel that inherits from both the IImageContract and IClientChannel interfaces:

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

    A channel is the WCF object through which the service and client pass each other information. Later, you will create the channel in your host application. Service Bus then uses this channel to pass the HTTP GET requests from the browser to your GetImage implementation. Service Bus also uses the channel to take the GetImage return value and translate it into an HTTP GETRESPONSE for the client browser.

  12. From the Build menu, click Build Solution to confirm the accuracy of your work.

Example

The following code example shows a basic interface that defines a Service Bus contract.

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)
        {
        }
    }
}

Now that the interface is created, proceed to Step 3: Implement a REST-based WCF Service Contract to use Service Bus to implement the interface.

See Also

Tasks

Step 3: Implement a REST-based WCF Service Contract to use Service Bus