Consuming the Services

by Walter Oliver

Introduction

Since Hosting Services Code Sample is implemented using Windows Communication Foundation, consuming it is fairly straightforward. Here, a few key points are described. Refer to WCF documentations for details regarding how to consume WCF services.

Client Configuration

Calling the services from a client application involves some configuration. The SampleWebClient project is an example of such an application. Generating the proxy for each of the services can be done either through Visual Studio® 2005, or by using the SvcUtil.exe command-line utility, found in \Program Files\Microsoft SDKs\Windows\v6.0\Bin. The following command generates the proxy for the WebManagementService.svc.

SvcUtil.exe http://<hostheader>/webmanagementservice.svc  /out:webmanagementservice.cs

The Proxy class can then be added to the project's Service References.

SvcUtil.exe has many options for controlling how the proxy classes are generated. Refer to SvcUtil related documentations for details. In the sample client application, we use the namespace option to dedicate the namespace for generated proxy classes to avoid the class conflicts.

The following screen shot shows a fragment of the proxy codes generated:

Screenshot showing a fragment of the generated code.

Client Web.Config

In the SampleWebClient, we provide the address and binding in the client's web.config file. Notice that there are binding and endpoint sections for each proxy class.

<binding name="WSHttpBinding_IWebManagementService" closeTimeout="00:01:00"
 openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
 bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
 maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text"
 textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
   <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
      maxBytesPerRead="4096" maxNameTableCharCount="16384" />
   <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
   <security mode="Message">
      <transport clientCredentialType="Windows" proxyCredentialType="None"    realm="" />
      <message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default" establishSecurityContext="true" />
   </security>
</binding>
<endpoint address="http://HostingServices/WebManagementService.svc"
 binding="wsHttpBinding"  bindingConfiguration="WSHttpBinding_IWebManagementService"
 contract="Microsoft.Hosting.Web.Client.WebManagement.IWebManagementService" name="WSHttpBinding_IWebManagementService">
      <identity>
            <userPrincipalName value="IIS7SHWS.IIS7Live\administrator" />
      </identity>
</endpoint>

When moving the client application from one environment to another, ensure that the endpoint address and userPrincipalName are modified to reflect the correct environment.

Implementing the Proxy

From the client application, add the System.ServiceModel namespace as well as the appropriate subsystem namespace.

using System.ServiceModel;
using Microsoft.Hosting.Web.Client.WebManagement;
using Microsoft.Hosting.Web.Client.WebProvisioning;

To call a service, you must first instantiate a proxy. The following line instantiates the proxy object for the Web subsystem's provisioning operation.

WebProvisioningServiceClient client = new WebProvisioningServiceClient();

Call the method to be executed, passing the appropriate parameter. In cases where the parameter consists of more complex data types, find the definition in the corresponding Data Contract class.

status = client.StartSite(sitename);

Then close the proxy. Closing the proxy terminates the session with the service and closes the connection.

client.Close();

Common Scenarios

The following CreateWebSite method creates a site, based on the site properties set in the WebSiteProvisioningRequest parameter.

WebProvisioningServiceClient.CreateWebSite(WebSiteProvisioningRequest request)
WebSiteProvisioningRequest exists in the Microsoft.Hosting.Web.Client.WebManagement.DataContract namespace. It is shown below.
public class WebSiteProvisioningRequest
public class WebSiteProvisioningRequest
{
    #region Fields
    private long _siteId;
    private string _siteName;
    private string _domainName;
    private string _userName;
    private string _password;
    private string _contentPath;
    private bool _useDefaultContentStructure;
    private string _physicalRootPath; 
    private string _logPath;
    private string _faultRequestsLoggingPath;
    private bool _createNewApplicationPool;
    private string _applicationPoolName;
    private bool _startSite;
    private BindingInfo _bindingInfo;
    //give the option for specifing to use an existing application pool or to create a new          application pool
    #endregion 
}

The WebSiteProvisioningRequest class contains properties to:

  • Create an Application pool
  • Create a site
  • Create the default application
  • Create the default virtual directory
  • Add the bindings

In addition, it configures logging and fault logging.

C# Sample

The following code sample demonstrates the creation of a website using the service. You must instantiate the WebProvisioningServiceClient proxy. The CreateWebSite(WebSiteProvisioningRequest request) method requires a parameter. All data types used in the methods are found in the corresponding Data Contract class. In this case, the WebSiteProvisioningRequest object can be found in the Microsoft.Hosting.Web.DataContract namespace.

The fault contracts apply to all subsystems and can be implemented as shown in the code below.

WebProvisioningServiceClient client = new WebProvisioningServiceClient();
try
{
  BindingInfo binding = new BindingInfo();
  binding.Protocol ="http"; 
  binding.IPAddress ="*"; //all ip addresses
  binding.TCPPort = 80;
  binding.HostHeader ="www.contoso.com";
  WebSiteProvisioningRequest request = new WebSiteProvisioningRequest();
  request.SiteName ="www.contoso.com";
  request.DomainName =string.Empty;
  request.UserName ="Testuser";
  request.Password ="pass@word1";
  request.ContentPath = @"c:\contents\";
  request.UserDefaultContentStructure = false;
  request.PhysicalRootPath = @"c:\contents\www.contoso.com";
  request.LogPath = @"c:\contents\www.contoso.com\logs";
  request.FaultRequestsLoggingPath = c:\contents\www.contoso.com\logs\FailedRequestLogs";
  request.Binding = binding;
  request.CreateNewApplicationPool = true;
  request.ApplicationPoolName = "TestAppPool";
  request.StartSite = true;
  request.SiteId = 0;
  if (client.CreateWebSite(request))
  this.lblResult.Text = "Web Site: " + request.SiteName + " has been successfully created.";
  client.Close();
}
catch (FaultException<HostingServiceFault> ex)
{
  this.lblResult.Text = "FaultException<HostingServiceException>: Hosting service fault while doing " + 
  ex.Detail.Operation + ". Error: " + ex.Detail.ErrorMessage;
  client.Abort();
}
  catch (FaultException ex)
{
  this.lblResult.Text = "Add Web Site Failed with unknown faultexception: " + e.GetType().Name + " - " + ex.Message;
  client.Abort();
}
  catch (Exception ex)
{
  this.lblResult.Text = "Failed with exception: " + ex.GetType().Name + " - " + ex.Message;
  client.Abort();
}

For more examples, refer to the sample web client application included with the Visual Studio Solution.