Building a WCF Service

Building a WCF service is not hard to accomplish. Using Visual Studio 2012, you'll see the WCF new project templates shown in Figure 11.2. One word of warning, however—in order to host a WCF service you'll need Administrator rights. Before attempting to replicate all of the steps in the sample, make sure you've started Visual Studio using the ‘Run as Administrator' option from the context menu.

Figure 11.2 New WCF project templates

11.2

When you build a WCF project in this manner, the idea is that you build a traditional class library that is compiled down to a DLL that can then be added to another project. The separation of code and use of multiple projects is a powerful tool for managing complexity on larger projects. That said, though, you can also just as easily build a WCF service directly in your .NET project, whether that is a console application or a Windows Forms application.

This example will first create a new WCF service in a Service Library. It then demonstrates how to host the WCF service inside a console application. Start by creating a new Service Library with the name ProVB_WCFCalculatorLibrary.

Once you have created your new library project, Visual Studio will look similar to what is shown in Figure 11.3.

Figure 11.3 WCF project template interface definition

11.3

This example first demonstrates how to build the WCF service. It then demonstrates how to build a console application that will host this service, and finally demonstrates how to leverage Visual Studio 2010 to test this service.

Creating the Interface

To create your service, you need a service contract, which is the interface of the service. This consists of all the methods exposed, as well as the input and output parameters that are required to invoke the methods. To accomplish this task, rename the file IService1.vb to ICalculator.vb. Then replace the contents of the generated file with the code presented in Listing 11.1.

Listing 11.1 : Service Interface Definition—ICalculator.vb

<ServiceContract()>
Public Interface ICalculator
    <OperationContract()>
    Function Add(ByVal a As Integer, ByVal b As Integer) As Integer
    <OperationContract()>
    Function Subtract(ByVal a As Integer, ByVal b As Integer) As Integer
    <OperationContract()>
    Function Multiply(ByVal a As Integer, ByVal b As Integer) As Integer
    <OperationContract()>
    Function Divide(ByVal a As Integer, ByVal b As Integer) As Integer
End Interface

This is pretty much the normal interface definition you would expect, but with a couple of new attributes included. The <ServiceContract()> attribute is used to define the class or interface as the service class, and it needs to precede the opening declaration of the class or interface.

Within the interface, four methods are defined. Each of these methods is going to be exposed through the WCF service as part of the service contract, so they all require that the <OperationContract()> attribute be applied to them.

Utilizing the Interface

The next step is to create a class that implements the interface. Not only is the new class implementing the interface defined, it is also implementing the service contract. From Solution Explorer, right-click on the generated Service1.vb file and rename this file as Calculator.vb. Next, replace the code in this file with the code shown in Listing 11.2.

Listing 11.2 : Calculator Implementation—Calculator.vb

Public Class Calculator
    Implements ICalculator
    Public Function Add(ByVal a As Integer,
                        ByVal b As Integer) As Integer _
                    Implements ICalculator.Add
        Return (a + b)
    End Function
    Public Function Subtract(ByVal a As Integer,
                             ByVal b As Integer) As Integer _
                         Implements ICalculator.Subtract
        Return (a - b)
    End Function
    Public Function Multiply(ByVal a As Integer,
                             ByVal b As Integer) As Integer _
                         Implements ICalculator.Multiply
        Return (a * b)
    End Function
    Public Function Divide(ByVal a As Integer,
                           ByVal b As Integer) As Integer _
                       Implements ICalculator.Divide
        Return (a / b)
    End Function
End Class

From these new additions, you can see that nothing is done differently with the Calculator class than what you might do otherwise. It is a simple class that implements the ICalculator interface and provides implementations of the Add, Subtract, Multiply, and Divide methods.

With the interface and the class available, you now have your WCF service built and ready to go. The next step is to get the service hosted. This is a simple service. One of the simplicities of the service is that it exposes only simple types, rather than a complex type. This enables you to build only a service contract and not have to deal with construction of a data contract. Constructing data contracts is presented later in this chapter.

Hosting the WCF Service in a Console Application

The next step is to take the service just developed and host it in some type of application process. You have many available hosting options, including the following:

  • Console applications
  • Windows Forms applications
  • Windows Presentation Foundation applications
  • Managed Windows Services
  • Internet Information Services (IIS) 5.1
  • Internet Information Services (IIS) 6.0
  • Internet Information Services (IIS) 7.0 and the Windows Activation Service (WAS)

As stated earlier, this example hosts the service in a simple console application. There are a couple of ways to activate hosting—either through the direct coding of the hosting behaviors or through declarative programming (usually done via the configuration file).

For this example, the console application will define the host through coding the behaviors of the host environment directly. As mentioned at the start of this sample, in order to host a WCF service this way, you need to have started Visual Studio with the Run as Administrator menu link. If you are not running as administrator, you will get a permissions error when the console application attempts to start.

Using the File menu in Visual Studio, select Add ⇒ New Project to add a new Console Application to your solution. Name the new console application ProVB_ServiceHost. After creating the new project, right-click the project name in Solution Explorer and set this project to be the startup project.

Next, right-click the project and select Add Reference. You need to add two references for this console application to act as a service host. The first is available from the Solution ⇒ Projects tab, Add a reference to the ProVB_WCFCalculatorLibrary. After adding this reference, open the dialog a second time and switch to the Assemblies ⇒ Framework tab. Scroll down and select System .ServiceModel.dll, as shown in Figure 11.4.

Figure 11.4 Adding a reference to System.ServiceModel

11.4

You are now ready to start making changes to the code. The code shown in Listing 11.3 implements the console application:

Listing 11.3 : Calculator Host—ProVB_ServiceHost/Module1.vb

Imports System.ServiceModel
Imports System.ServiceModel.Description
        
Module Module1
    Sub Main()
        Using svcHost As New ServiceHost( _
                GetType(ProVB_WCFCalculatorLibrary.Calculator))
            Dim netBind As New NetTcpBinding(SecurityMode.None)
            svcHost.AddServiceEndpoint( _
                GetType(ProVB_WCFCalculatorLibrary.ICalculator),
                netBind,
                New Uri("net.tcp://localhost:8080/Calculator/"))
            Dim smb As New ServiceMetadataBehavior()
            smb.HttpGetEnabled = True
            smb.HttpGetUrl = New Uri("http://localhost:8000/Calculator")
            svcHost.Description.Behaviors.Add(smb)
            svcHost.Open()
            Console.WriteLine("Press <Enter> to close and end the Service Host")
            Console.ReadLine()
        End Using
    End Sub
End Module

A couple of things are going on in this file. First, in order to gain access to work with any of the WCF framework pieces, you need a reference to the System.ServiceModel and the System.ServiceModel.Description namespaces in the file. The System.ServiceModel gives you access to defining things such as the endpoints that you need to create, while the System.ServiceModel.Description namespace reference gives you access to defining things such as the WSDL file.

Remember that creating endpoints uses the ABC model (address, binding, and contract). The address part here is net.tcp://localhost:8080/Calculator. The binding is a TCP binding—NetTcpBinding—while the contract part is the ICalculator interface.

Many different bindings are available to you when coding WCF services. Here, this example makes use of the NetTcpBinding. The full list of available bindings is as follows:

  • System.ServiceModel.BasicHttpBinding
  • System.ServiceModel.Channels.CustomBinding
  • System.ServiceModel.MsmqBindingBase
  • System.ServiceModel.NetNamedPipeBinding
  • System.ServiceModel.NetPeerTcpBinding
  • System.ServiceModel.NetTcpBinding
  • System.ServiceModel.WebHTTPBinding
  • System.ServiceModel.WSDualHttpBinding
  • System.ServiceModel.WSHttpBindingBase

Clearly, several bindings are available. In the preceding example, the NetTcpBinding class is the transport pipe being used. This means that the service being built will be delivered over TCP. At this point your development environment should look similar to what is shown in Figure 11.5. However, before running the new console, let's look at the various commands it will use to host your custom service.

Figure 11.5 Editing the SecurityMode property in Visual Studio

11.5

In the first step of the example, for the console-application code, a ServiceHost object is established:

Using svcHost As New ServiceHost( _
                GetType(ProVB_WCFCalculatorLibrary.Calculator))

By working with the Using keyword, when the End Using statement is encountered, the ServiceHost object is destroyed. In the creation of the host, the Calculator type is assigned. From there, the endpoint is established. In this case, a NetTcpBinding object is created with a security setting of None through the command SecurityMode.None:

Dim netBind = New NetTcpBinding(SecurityMode.None)

This means that no security is applied to the message. The other options include Message, Transport, and TransportWithMessageCredential. The Message option signifies that the security credentials will be included in the message (in the SOAP header, for instance), whereas the Transport option indicates that the transport protocol provides the security implementation. The last option, TransportWithMessageCredential, means that the message contains some security credentials along with the transport protocol security provided by the transport protocol.

Once the NetTcpBinding object is in place, the next step is to finalize the endpoint creation. This is done through the use of the ServiceHost object's AddServiceEndpoint method:

svcHost.AddServiceEndpoint( _
    GetType(ProVB_WCFCalculatorLibrary.ICalculator),
    netBind,
    New Uri("net.tcp://localhost:8080/Calculator/"))

From this, you can see that the entire ABC statement is used in the creation of the endpoint, although not necessarily in ABC order; in fact, the first item defined is actually the “C”—the contract. This is done through the GetType(ICalculator)setting. The “B” is next (the binding) with the reference to the NetTcpBinding object. Then, finally, the “A” is defined through an instantiation of a Uri object pointing to net.tcp://localhost:8080/Calcuator/.

The next step is a process to bring forth the WSDL document so that it can be viewed by the developer consuming this service:

Dim smb As New ServiceMetadataBehavior()
smb.HttpGetEnabled = True
smb.HttpGetUrl = New Uri("http://localhost:8000/calculator")
serviceHost.Description.Behaviors.Add(smb)

This bit of code is the reason why the System.ServiceModel.Description namespace is imported into the file at the beginning. Here, a ServiceMetadataBehavior object is created, the object's HttpGetEnabled property is set to True, and the HttpGetUrl property is provided an address of http://localhost:8000/calculator. The documents can be located anywhere you like.

After the ServiceMetadataBehavior object is created as you wish, the next step is to associate this object with the ServiceHost through the serviceHost.Description.Behaviors.Add method.

After all of these items are defined, you need only open the ServiceHost for business, using the serviceHost.Open method. The console application is kept alive through the use of a Console .ReadLine method call, which waits for the end user to press the Enter key before shutting down the application. You want the Console.ReadLine command there because you want to keep the host open.

Compiling and running this application produces the results illustrated in Figure 11.6. Note that you may initially get a firewall warning when you run this application, but you'll want to allow access for this application to communicate (at least locally) through your local firewall. Additionally, if you didn't start Visual Studio with Administrator rights as noted at the beginning of this step, you'll get a runtime error related to permissions.

Figure 11.6 Running ProVB_ServiceHost to host the service

11.6

Keep in mind that your service is available only for as long as that console window is open and active; when you close the console you are stopping the listener for your new service. Also note that you aren't running the service within the Visual Studio's built-in tools. To do so you would need to edit the app.config file in the ProVB_WCFCalculatorLibrary project to properly reference your ICalculator interface.

Reviewing the WSDL Document

The preceding console-application code provides an instantiation of the ServiceMetadataBehavior object and defines a Uri object for it as well. You can simply type in that address to get at the WSDL file for the service you just built. Therefore, calling http://localhost:8000/calculator from your browser provides the WSDL file shown in Figure 11.7.

Figure 11.7 Looking at the WSDL in Internet Explorer

11.7

With this WSDL file, you can now consume the service it defines through TCP. Note the following element at the bottom of the document:

<wsdl:service name="Calculator">
   <wsdl:port name="NetTcpBinding_ICalculator"
    binding="tns:NetTcpBinding_ICalculator">
      <soap12:address location="net.tcp://localhost:8080/Calculator/" />
      <wsa10:EndpointReference>
         <wsa10:Address>net.tcp://localhost:8080/Calculator/</wsa10:Address>
      </wsa10:EndpointReference>
   </wsdl:port>
</wsdl:service>

This element in the XML document indicates that in order to consume the service, the end user needs to use SOAP 1.2 over TCP. This is presented through the use of the <soap12:address> element in the document. The <wsa10:EndpointReference> is a WS-Addressing endpoint definition.

Using this simple WSDL document, you can now build a consumer that makes use of this interface. Just as important, you have created not only a service that meets the standards for a Web service, but also a custom host that is communicating via standard protocols.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset