Namespaces

Note that the services built in the chapter have no defined namespaces. If you looked at the WSDL files that were produced, you would see that the namespace provided is http://tempuri.org. Obviously, you do not want to go live with this default namespace. Instead, you need to define your own namespace.

To accomplish this task, the interface's <ServiceContract()> attribute enables you to set the namespace:

<ServiceContract(Namespace:="http://www.Wrox.com/ns/")> _
Public Interface IHelloCustomer
    <OperationContract()> _
    Function HelloFirstName(ByVal cust As Customer) As String
    <OperationContract()> _
    Function HelloFullName(ByVal cust As Customer) As String
End Interface

Here, the <ServiceContract()> attribute uses the Namespace property to provide a namespace.

Building the Host

Next create a service host, using the same steps as before: Create a new Console Application project to act as the WCF service host. Name the new project ProVB_WCFWithDataContractHost and change the Module1.vb file so that it becomes the host of the WCF service you just built. Keep in mind that you'll need to add the appropriate project reference and System.ServiceModel references to the code. Once that is complete, the updated code will look similar to Listing 11.9:

Listing 11.9 : Service Host Implementation—ProVB_WCFWithDataContractHostModule1.vb

Imports System.ServiceModel
Imports System.ServiceModel.Description
        
Module Module1
    Sub Main()
        Using svcHost =
           New ServiceHost(GetType(ProVB_WCFWithDataContract.HelloCustomer))
            Dim netBind = New NetTcpBinding(SecurityMode.None)
     svcHost.AddServiceEndpoint(GetType(ProVB_WCFWithDataContract.IHelloCustomer),
                          netBind,
                          New Uri("net.tcp://localhost:8080/HelloCustomer/"))
            Dim smb = New ServiceMetadataBehavior()
            smb.HttpGetEnabled = True
            smb.HttpGetUrl = New Uri("http://localhost:8000/HelloCustomer")
            svcHost.Description.Behaviors.Add(smb)
            svcHost.Open()
            Console.WriteLine("Press the <ENTER> key to close the host.")
            Console.ReadLine()
        End Using
    End Sub
End Module

This host uses the IHelloCustomer interface and builds an endpoint at net.tcp://localhost:8080/HelloCustomer. This time, however, you'll have this running when you map your interface so you can see an example of the TCP binding. Build your solution and show all files in the Solution Explorer for your host project. You can then see the bin folder for your project, which contains the Debug folder. Right-click the Debug folder and from the context menu select Open Folder in Windows Explorer.

This should give you a view similar to what is shown in Figure 11.13. Right-click on ProVB_WCFWithDataContractHost and run your application as Administrator (you may be prompted to resolve a firewall issue and to confirm that you want to elevate the privileges of this process) to start your WCF host outside of Visual Studio. By starting this application outside of Visual Studio, you can directly reference the TCP-based binding you created as part of your host console from the Add Service Reference dialogue. Just leave this running in the background as you continue this example.

Figure 11.13 Accessing the compiled assembly to test run as Administrator

11.13

Building the Consumer

Now that the service is running and in place, the next step is to build the consumer. To begin, add a new Console Application project to your Service Library solution called ProVB_HelloWorldConsumer. Right-click on the project and select Add Service Reference from the options provided. In short you are going to create another copy of the service host created in the previous example.

From the Add Service Reference dialog, target your custom service host by entering http://localhost:8000/HelloCustomer as the service URI. Then simply rename the default ServiceReference1 with the name HelloCustomerService as shown in Figure 11.14.

Figure 11.14 Add a service reference to your running service

11.14

This will add the changes to the references and the app.config file just as before, enabling you to consume the service. You can use the steps to create the service host from the first sample, but update the connections to reference the new service, as shown in Listing 11.10.

Listing 11.10 : Service Client Code—ProVB_HelloWorldConsumerModule1.vb

Module Module1
    Sub Main()
        Dim svc As New HelloCustomerService.HelloCustomerClient()
        Dim cust As New HelloCustomerService.Customer()
        Dim result As String
        svc.Open()
        Console.WriteLine("What is your first name?")
        cust.FirstName = Console.ReadLine()
        Console.WriteLine("What is your last name?")
        cust.LastName = Console.ReadLine()
        result = svc.HelloFullName(cust)
        svc.Close()
        Console.WriteLine(result)
        Console.ReadLine()
    End Sub
End Module

As a consumer, once you make the reference, the service reference doesn't just provide a HelloCustomerClient object; you will also find the Customer object that was defined through the service's data contract.

Therefore, the preceding code block just instantiates both of these objects and builds the Customer object before it is passed into the HelloFullName method provided by the service. Running this bit of code will return the results shown in Figure 11.15.

Figure 11.15 Consuming the service

11.15

Looking at WSDL and the Schema for HelloCustomerService

After you made the reference to the HelloCustomer service, it was possible for you to review the WSDL in your new reference. With the Solution Explorer showing all files, you'll see the HelloCustomer1.wsdl within your solution. You can open this file to look at the WSDL, where you will find the following XSD imports:

<wsdl:types>
  <xsd:schema targetNamespace="http://www.Wrox.com/ns/Imports">
    <xsd:import schemaLocation="http://localhost:8000/HelloCustomer?xsd=xsd0"
    namespace="http://www.Wrox.com/ns/" />
    <xsd:import schemaLocation="http://localhost:8000/HelloCustomer?xsd=xsd1"
     namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
    <xsd:import schemaLocation="http://localhost:8000/HelloCustomer?xsd=xsd2"
     namespace="http://schemas.datacontract.org/2004/07/
     ProVB_WCFWithDataContract" />
  </xsd:schema>
</wsdl:types>

http://localhost:8000/HelloCustomer?xsd=xsd2 provides the details about your Customer object. The code from the file HelloCustomer2.xsd, which is part of your reference definition, is shown here:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema
   xmlns:tns="http://schemas.datacontract.org/2004/07/ProVB_WCFWithDataContract"
    elementFormDefault="qualified"
    targetNamespace=
            "http://schemas.datacontract.org/2004/07/ProVB_WCFWithDataContract"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:complexType name="Customer">
    <xs:sequence>
      <xs:element minOccurs="0" name="FirstName" nillable="true"
                                               type="xs:string" />
      <xs:element minOccurs="0" name="LastName" nillable="true"
                                               type="xs:string" />
    </xs:sequence>
  </xs:complexType>
  <xs:element name="Customer" nillable="true" type="tns:Customer" />
</xs:schema>

This is an XSD description of the Customer object. Making a reference to the WSDL that includes the XSD description of the Customer object causes the auto-generated proxy class (located in the file Reference.vb) to create the following class as part of the proxy (this code follows the Namespace declaration in the downloadable sample):

    <System.Diagnostics.DebuggerStepThroughAttribute(),  _
System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization" _
 , "4.0.0.0"),  _
     System.Runtime.Serialization.DataContractAttribute(Name:="Customer", _
    [Namespace]:= _
    "http://schemas.datacontract.org/2004/07/ProVB_WCFWithDataContract"),  _
     System.SerializableAttribute()>  _
    Partial Public Class Customer
        Inherits Object
        Implements System.Runtime.Serialization.IExtensibleDataObject,
                   System.ComponentModel.INotifyPropertyChanged
        <System.NonSerializedAttribute()>  _
        Private extensionDataField As _
                      System.Runtime.Serialization.ExtensionDataObject
        
        <System.Runtime.Serialization.OptionalFieldAttribute()>  _
        Private FirstNameField As String
        
        <System.Runtime.Serialization.OptionalFieldAttribute()>  _
        Private LastNameField As String
        
        <Global.System.ComponentModel.BrowsableAttribute(false)>  _
        Public Property ExtensionData() As _
        System.Runtime.Serialization.ExtensionDataObject _
    Implements System.Runtime.Serialization.IExtensibleDataObject.ExtensionData
            Get
                Return Me.extensionDataField
            End Get
            Set
                Me.extensionDataField = value
            End Set
        End Property
        
        <System.Runtime.Serialization.DataMemberAttribute()>  _
        Public Property FirstName() As String
            Get
                Return Me.FirstNameField
            End Get
            Set
                If (Object.ReferenceEquals(Me.FirstNameField, value) <>  _
                                                                true) Then
                    Me.FirstNameField = value
                    Me.RaisePropertyChanged("FirstName")
                End If
            End Set
        End Property
        
        <System.Runtime.Serialization.DataMemberAttribute()>  _
        Public Property LastName() As String
            Get
                Return Me.LastNameField
            End Get
            Set
                If (Object.ReferenceEquals(Me.LastNameField, value) <> _
                                                              true) Then
                    Me.LastNameField = value
                    Me.RaisePropertyChanged("LastName")
                End If
            End Set
        End Property

As you can see, Visual Studio and WCF provide the tools you need to define and share complex data types across a distributed system. Combined with the other powerful features supported by WCF, you have the tools to build robust, enterprise-quality distributed solutions.

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

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