Previously we discussed a way to host a WCF library in IIS. We’ll now explore ways to consume the service, via a WPF client, in a few simple steps.
Step 1: Create a WPF application and lay out some controls as in the diagram below:
The XAML for window is as follows (for now ignore the controls with rest postfix):
<Window x:Class="Demo.Wcf.WpfClient.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="769">
<Grid>
<TextBox Height="23" HorizontalAlignment="Left" Margin="145,12,0,0" Name="txtRegistrant" VerticalAlignment="Top" Width="120" />
<Button Height="23" HorizontalAlignment="Left" Margin="91,59,0,0" Name="btnRegisterWs" VerticalAlignment="Top" Width="75" Click="btnRegisterWs_Click">Register(ws)</Button>
<Button Height="23" HorizontalAlignment="Right" Margin="0,59,118,0" Name="btnRegisterRest" VerticalAlignment="Top" Width="75">Register(rest)</Button>
<Button HorizontalAlignment="Left" Margin="10,59,0,0" Name="btnListWs" Width="75" Height="23" VerticalAlignment="Top" Click="btnListWs_Click">List(ws)</Button>
<Button HorizontalAlignment="Right" Margin="0,59,199,0" Name="btnListRest" Width="75" Height="23" VerticalAlignment="Top">List(rest)</Button>
<my:DataGrid AutoGenerateColumns="true" Margin="10,88,12,0" Name="dg" xmlns:my="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit" />
<Button Height="23" HorizontalAlignment="Left" Margin="172,59,0,0" Name="btnDeleteWs" VerticalAlignment="Top" Width="75" Click="btnDeleteWs_Click">Delete(ws)</Button>
<Label Height="28" HorizontalAlignment="Left" Margin="10,10,0,0" Name="lblRegistrant" VerticalAlignment="Top" Width="120">Registrant Name</Label>
<Button Height="23" HorizontalAlignment="Right" Margin="0,59,37,0" Name="btnDeleteRest" VerticalAlignment="Top" Width="75">Delete(rest)</Button>
</Grid>
</Window>
Step 2: Add a service reference to the WCF service we had previously created and deployed on IIS
- Click on the Add Service Reference… context menu
- Enter the URI of the hosted service in the Address textbox of the Add Service Reference dialog box and click on Go
- Available services should now be listed in the Services listbox and corresponding operations on the right when you select a service from the left
- Enter a meaningful name for the service reference in the Namespace textbox
- Click OK to complete adding the service reference and close the dialog box
The diagram below samples the entry in the Add Service Reference dialog box:
Explore the newly added service reference in object browser and notice that there are 4 entries:
- IRegistrationService
- IRegistrationServiceChannel
- Registration
- RegistrationServiceClient
Entries 1 and 3 are interface and payload class that we wrote in our WCF library. Entries 2 and 4 are auto generated and we’ll discuss the later in a little more detail. Click on the RegistrationServiceClient node to reveal the public API of the class.
Notice that it appears to have the same API as our WCF service’s RegistrationService class with 5 constructors, even though, our class had none. These constructors are auto generated and provide additional flexibility in selecting specific endpoints for a particular communication. Also note that all API on the concrete service class beyond that supported by the IRegistrationService interface, if any, is removed from this client concrete proxy class.
Step 3: Wire the three button click events to register, list, and delete registrations as in the sample code below:
private void btnListWs_Click(object sender, RoutedEventArgs e)
{
using (RegSvcRef.RegistrationClient svc = new Demo.Wcf.WpfClient.RegSvcRef.RegistrationClient("WSHttpBinding_IRegistration"))
dg.ItemsSource = svc.GetRegistrationList();
}private void btnRegisterWs_Click(object sender, RoutedEventArgs e)
{
Registration reg = new Registration();
reg.RegistrantName = txtRegistrant.Text;
using (RegSvcRef.RegistrationClient svc = new Demo.Wcf.WpfClient.RegSvcRef.RegistrationClient("WSHttpBinding_IRegistration"))
{
svc.Register(reg);
dg.ItemsSource = svc.GetRegistrationList();
}
}private void btnDeleteWs_Click(object sender, RoutedEventArgs e)
{
using (RegSvcRef.RegistrationClient svc = new Demo.Wcf.WpfClient.RegSvcRef.RegistrationClient("WSHttpBinding_IRegistration"))
{
string id = (dg.SelectedValue as Registration).Id;
if (!string.IsNullOrEmpty(id))
{
svc.DeleteRegistration(id);
dg.ItemsSource = svc.GetRegistrationList();
}
}
}
You should now have a functional WPF client consuming our WCF service, test it out and feel free to send me any questions you may have. In the next sequel, we’ll modify this client application to consume the WCF service asynchronously.
TANTH said:
if a client (Publisher) sends some data to the service (Subscriber) via Routing Service, how can we retreive the data in the Subscriber in WPF? I understand that we need to do some kind of marshalling to be done as the WCF service is a non-GUI thread, and to receive data in WPF in a GUI thread, there is some deadlock issue.
dkwebdeveloper said:
Could not find endpoint element with name ‘WSHttpBinding_IRegistration’ and contract ‘ServiceReferenceRef.IRegistrationService’ in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this name could be found in the client element.
a1ashiish said:
Nicely written post. Please find below the other link that explains step by step process to call WCF service in WPF application.
http://adf.ly/JM6sL