Building Blocks for a WCF Service Web Site

In this seventh part of a ten-part series focusing on the Windows Communication Foundation (WCF), aka Indigo, you'll learn how to work with service and client behaviors, and start creating a WCF Service web site. This article is excerpted from chapter 1 of the book Learning WCF A Hands-on Guide, written by Michele Leroux Bustamante (O'Reilly, 2007; ISBN: 0596101627). Copyright © 2007 O'Reilly Media, Inc. All rights reserved. Used with permission from the publisher. Available from booksellers or direct from O'Reilly Media.

Contributed by
Rating: 5 stars5 stars5 stars5 stars5 stars / 3
April 24, 2008
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

Working with Behaviors

As you've seen, the ServiceHost is initialized by the <service> configuration section associated with its service type. At least one endpoint must be configured for the service to be useful to clients. In this lab, a single service endpoint and a metadata exchange endpoint are exposed--both over HTTP. While endpoints describe where to reach the service, which operations are available at the specified address, and what protocols are required--behaviors affect the service model locally at the client or service. What that means is that behaviors are not exposed as part of metadata, and they are not shared between clients and services. Instead, they locally affect how the service model processes messages.

Behaviors can be defined in configuration or in code. Different behaviors are available to clients and services, since the local affect on the service model also differs.

Service behaviors

Service behaviors are types that implement IServiceBehavior from the
System.ServiceModel.Description namespace. There are service behaviors to control debugging, metadata, security features, serialization, and throttling. When enabled, each behavior interacts with the service model to achieve its goal. For example, when the metadata behavior is enabled, the service model will allow requests to a metadata exchange endpoint. Otherwise, it will not.

Service behaviors are configured in the<serviceBehaviors>section. The following example illustrates enabling service debug and service metadata behaviors:

  <behaviors>
     
<serviceBehaviors>
       
<behavior name="serviceBehavior">
         
<serviceDebug includeExceptionDetailInFaults="true"/>
          
<serviceMetadata />
      </behavior>
   
</serviceBehaviors>
  </behaviors>

To associate a set of behaviors with a service use thebehaviorConfigurationattribute of the<service>section (see Example 1-8).

Example 1-8. Associating a service behavior to a service

<system.serviceModel>
 
<behaviors>
   
<serviceBehaviors>
     
<behavior name="serviceBehavior">
       
<serviceMetadata />
     
</behavior>
   
</serviceBehaviors>
  </behaviors>
  <services>
   
<service behaviorConfiguration="serviceBehavior" name="Host.HelloIndigoService" >
   
...
   
</service>
 
</services>
</system.serviceModel>

You may forget to make the association between the service and behavior at least a few times. Don't forget to double-check your configuration when you aren't seeing the expected results at runtime!

You can also programmatically configure service behaviors through theServiceHostinstance. TheDescriptionproperty of theServiceHosthas aBehaviorscollection. You can see if a behavior exists by calling theFind<T>()method on the collection. You can add new behaviors by callingAdd()on the collection. Example 1-9 shows an example that looks to see if theServiceMetadataBehaviorexists, and if not adds it to the collection and enables browsing.

Example 1-9. Adding the metadata service behavior programmatically

ServiceHost host = new ServiceHost(typeof(HelloIndigo.HelloIndigoService);

ServiceMetadataBehavior mexBehavior = host.Description.Behaviors. Find<ServiceMetadataBehavior>();

if (mexBehavior == null)
{
 
mexBehavior = new ServiceMetadataBehavior();
 
mexBehavior.HttpGetEnabled = true;
 
host.Description.Behaviors.Add(mexBehavior);
}

host.Open();

Client behaviors

Client behaviors implement IEndpointBehavior, also from the System.ServiceModel.Description namespace. There are client behaviors to control debugging, security, serialization, timeouts, and routing. Endpoint behaviors interact with the service model at the client. Endpoint behaviors are configured in the <endpointBehaviors> section. The following example enables exception debugging for callbacks:

  <behaviors>
    <endpointBehaviors>
      <behavior>
        <callbackDebug includeExceptionDetailInFaults="true"/>
      </behavior>
    </endpointBehaviors>
  </behaviors>

Endpoint behaviors are associated with client endpoints using thebehaviorConfigurationattribute of the<endpoint>section (see Example 1-10).

Example 1-10. Associating an endpoint behavior to a client endpoint

<system.serviceModel>
 
<behaviors>
   
<serviceBehaviors>
     
<behavior name="clientBehavior">
        ...
     
</behavior>
   
</serviceBehaviors>
 
</behaviors>
  <client>
   
<endpoint address="net.tcp://localhost:9000/" binding="netTcpBinding" contract="Client.localhost.IHelloIndigoService" behaviorConfiguration="clientBehavior">
   
</endpoint>
  </client>
</system.serviceModel>

To programmatically configure endpoint behaviors, you can use the object model of the client proxy. TheEndpointproperty of the client proxy has aBehaviorscollection through which you can search for existing behaviors and add behaviors--similar to the way you would for theServiceHost. Example 1-11 shows an example that looks to see if theServiceDebugBehaviorexists, and if not adds it to the collection.

Example 1-11. Adding the debug service behavior programmatically

HelloIndigoServiceClient proxy = new HelloIndigoServiceClient();

ServiceDebugBehavior debugBehavior = proxy.Endpoint.Behaviors.Find<ServiceDebugBehavior>();

if (debugBehavior == null)
{
 
debugBehavior = new ServiceDebugBehavior();

 debugBehavior.IncludeExceptionDetailInFaults = true;
 
proxy.Endpoint.Behaviors.Add(debugBehavior);
}

I will explore other behaviors for the client and service throughout this book as I review features related to each behavior. At this point, I want you to understand how services and client endpoints are related to behaviors.

Proxy Initialization

For a client to invoke service operations, it must open a communication channel to a particular service endpoint. This channel is bound to a particular endpoint--its address, binding, and contract. This is done by creating a proxy.

In the first lab, a proxy is created directly by using the channel factory:

  IHelloIndigoService proxy = 
  ChannelFactory<IHelloIndigoService>. CreateChannel(new BasicHttpBinding(), new
  EndpointAddress("http://localhost:8000/HelloIndigo/ HelloIndigoService"));

This approach assumes that:

  • You have prior knowledge of the endpoint address.
  • A copy of the service contract definition is locally available.
  • You have prior knowledge of the required protocols or binding configuration.

If you own both sides (client and service), it is feasible to share an assembly that contains service metadata and to separately communicate the address and binding requirements. When you don't own both sides, generating the proxy is a more effective way to import the metadata necessary to construct the client channel. In this lab, the proxy is generated with SvcUtil. This proxy includes a generated copy of the service contract and a channel wrapper to simplify the client code necessary to consume the service. SvcUtil also generates the service model configuration necessary to initialize the proxy.

The service contract generated by SvcUtil looks similar to the contract at the service with the exception of additional details specified in theServiceContractAttributeandOperationContractAttribute, shown inExample 1-12 .

Example 1-12. Service contract generated by SvcUtil

[System.ServiceModel.ServiceContractAttribute(Namespace= "http://www.thatindigogirl.com/samples/2006/06", ConfigurationName="Client.localhost. IHelloIndigoService")]
public interface IHelloIndigoService
{
 
[System.ServiceModel.OperationContractAttribute(Action=
"http://www.thatindigogirl.com/samples/2006/ 06/IHelloIndigoService/HelloIndigo", ReplyAction= "http://www.thatindigogirl.com/samples/2006/06
 /IHelloIndigoService/HelloIndigoResponse")]

   string HelloIndigo();
}

The namespace specified by theServiceContractAttributeis the same as at the service. This is critical to compatible message serialization.

The SvcUtil that generated the client-side service contract also generated a proxy type. The proxy type is a partial class that inheritsClientBase<T>from theSystem.ServiceModelnamespace (T is the service contract type). As shown in bold in Example 1-13, the proxy exposes service contract operations and internally uses its reference to the client communication channel to invoke each service operation. In fact, this inner channel reference is like the one you previously created with the channel factory.

Example 1-13. Proxy type generated by SvcUtil

public partial class HelloIndigoServiceClient: System.ServiceModel.ClientBase<Client. localhost.IHelloIndigoService>, Client.localhost.IHelloIndigoService
{
 
...overloaded constructors

  public string HelloIndigo()
  {
    return base.Channel.HelloIndigo();
  }
}

When the first operation is invoked on this proxy, the inner channel is created based on the endpoint configuration for the proxy. Since in this lab only one endpoint is available, the construction of the proxy looks something like this:

  HelloIndigoServiceClient proxy = new HelloIndigoServiceClient();

If there are several endpoints to choose from in the<client>configuration section, you are required to provide an endpoint configuration name to the proxy constructor:

  // Proxy construction
  HelloIndigoServiceClient proxy = new HelloIndigoServiceClient("basicHttp");

  // Endpoint configuration
  <endpoint address=http://localhost:8001/HelloIndigo/ HelloIndigoService
  binding="basicHttpBinding" name="basicHttp" contract="Host.IHelloIndigoService" />

Once the client channel has been used (by invoking an operation), the proxy is bound to the endpoint configuration that initialized it. The same proxy instance cannot be used to invoke another service endpoint, and no changes to protocols or behaviors are allowed. A new proxy (channel) must be constructed if such changes are required.

Hosting a Service in IIS

How messages reach a service endpoint is a matter of protocols and hosting. IIS can host services over HTTP protocol, the Windows Activation Service (WAS) can
support others such as TCP and named pipes, and self-hosting can support many protocols and includes several deployment options such as console or Windows Forms applications and Windows services. Selecting a hosting environment has nothing to do with service implementation, but everything to do with service deployment and overall system design.

This lab will show you how to host an existing service type as part of a web site hosted in IIS. In the process, I'll also be illustrating other extended concepts such as:

  • The WCF Service web site template
  • Message-based activation
  • Additional metadata behavior settings
  • Exporting service descriptions
  • Consuming service description documents to generate client code

As always, after the lab I'll describe some of these features in greater detail.


Lab: Creating an IIS Host and Browsing Metadata


For this lab, you will work with an existing solution that contains a completed service library and shell client application. Using Visual Studio templates, you'll create a new IIS web site project that contains a service and modify it to host a preexisting service. To consume the service, you'll generate a client proxy from static service documentation exported using SvcUtil.

Creating a WCF Service web site

The first thing to do is create a WCF-enabled web site using the WCF Service template, which is new to WCF. When services are added to a web site, the supplied sample service is accompanied by a .svc file, the web server endpoint.

  1. Open the startup solution for the lab, located at <YourLearningWCFPath>\Labs\ Chapter1\IISHostedService\IISHostedService.sln. This solution contains a copy of theHelloIndigoproject from earlier labs and a shell client application.
  2. You are going to create a new web site to host the service. Go to Solution Explorer, right-click the solution node and select Add -> New Web Site. Select the WCF Service template and make sure the location type for the new web site is HTTP (see Figure 1-25). Set the location value to http://localhost/IISHostedService.

    When Visual Studio creates a new HTTP web site, a virtual application is created in IIS pointing to a directory beneath c:\inetpub\wwwroot (or wherever your Default Web Site is pointing). In Figure 1-25, the path to theIISHostedServiceproject might be c:\ inetpub\wwwroot\IISHostedService.
  3. The WCF Service template generates a new web site with a default service implementation. You can delete the service implementation since you will be hosting an existing service. Go to Solution Explorer and expand the App_Code folder for the web site (see Figure 1-26). There you'll see the file Service.cs. Delete it from the project.
  4. Go to the web site project and add a reference to theHelloIndigoproject, which contains the service you're about to host.
  5. You now can modify the web endpoint for the service so that it is associated with the correct service type. Open Service.svc in the code window and modify the@ServiceHostdirective to associate the web endpoint with the service typeHelloIndigo.HelloIndigoService, as shown here:

      <%@ ServiceHost Service="HelloIndigo.HelloIndigoService" %>

    Now, when a request arrives to Service.svc, the service model will activate a newServiceHostinstance associated with theHelloIndigoServicetype.
  6. The WCF Service template also generated configuration settings for the host, but these settings are based on the service supplied by the template. You must modify these settings to reflect the correct service contract and service type.

    Open the web.config file and find the<service>section. Change the name attribute of the<service>section toHelloIndigo.HelloIndigoServiceand change the contract attribute of the<endpoint>section toHelloIndigo.IHelloIndigoService. While you're at it, change the binding tobasicHttpBindinginstead ofwsHttpBinding. The result is shown here:

      <service type="HelloIndigo.HelloIndigoService"
      behaviorConfiguration="returnFaults">
        <endpoint contract="HelloIndigo.IHelloIndigoService"
      binding="basicHttpBinding"/>
      </service>

You now have a web site that will expose an endpoint to reachHelloIndigoService. Before generating the client proxy, I'll show you some useful metadata features.

Please check back next week for the continuation of this article.

blog comments powered by Disqus
BRAINDUMP ARTICLES

- Microsoft Windows 8 Committed to Cloud Compu...
- Independent Developers Favor Windows Phone 7
- Dell Introduces VMware-based Cloud
- Microsoft and Skype Agree to Acquisition Deal
- Transfer Contacts in Microsoft Outlook
- Zune`s Next Steps
- Safari Books Online Review
- Does Microsoft Get Touch Screens Now?
- Microsoft`s Record Quarterly Earnings Not En...
- Basic Operations and Registers in Assembly
- Assembly Coding within Visual C/C++ IDE
- New Microsoft Office Coming with a Twist
- Microsoft`s FUSE Labs Unveils Spindex Social...
- HP Slate with Windows 7: Dead or Alive?
- Windows Phone 7 Mobile OS to Rival Android a...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
 
 
 

ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 1 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials