Monday, 4 June 2012

Hosting WCF Services by extending SeviceHostingFactory - Part 2

In previous post, we had seen the service application which expose the Customer data by extending SeviceHostingFactory. This is the continuation post, which explains the client application which consume the customer service.

The ServiceConsumer (Client)
This project contains the UI files and the helper classes for consuming the service to shows the data on the screen.

It contains following files to show the customer entry screen and do the CRUD operation.
  1. Default.aspx, Default.aspx.cs – UI Class for Customer entry screen.
  2. CustomerServiceClient.cs – This is the customer service client file which can be creating from svcutil utility. For more information refer the url http://msdn.microsoft.com/en-us/library/aa347733.aspx.
    For Ex: svcutil.exe /language:cs /out:c:\pro.cs /config:c:\con.config http://localhost/DNT.WCFHost/CustomerService.svc
  3. EntityClient.cs – This class contains the entity class defined in DNT.Entity project. You can get the same from the output file of svcutil utility.
  4. CustomerServiceHelper.cs – This is a helper class for doing CRUD operations. This class interacts with the customer service and UI classes calls this helper class instead of the service directly.
  5. Web.Config – This is the configuration file which includes the service configuration.
The source code for all these files shown below except CustomerServiceClient.cs and EntityClient.cs which can be created using svcutil.

CustomerServiceHelper.cs
public class CustomerServiceHelper
{
    public IList<Customer> GetAll()
    {
        IList<Customer> customers = new List<Customer>();

        Run(delegate(ICustomerService client)
        {
            customers = client.GetAll();
        });

        return customers;
    }

    public Customer Get(string customerId)
    {
        Customer customer = new Customer();

        Run(delegate(ICustomerService client)
        {
            customer = client.Get(customerId);
        });

        return customer;
    }

    public int Save(Customer customer, bool IsEdit)
    {
        int intResult = 0;
        Run(delegate(ICustomerService client)
        {
            if (IsEdit == true)
            {
                intResult = client.Update(customer);
            }
            else
            {
                intResult = client.Create(customer);
            }
        });

        return intResult;
    }

    public int Delete(string customerId)
    {
        int intResult = 0;
        Run(delegate(ICustomerService client)
        {
            if (customerId.Trim().Length != 0)
            {
                intResult = client.Delete(customerId);
            }
        });

        return intResult;
    }

    private void Run(Action<ICustomerService> program)
    {

        CustomerServiceClient client = new CustomerServiceClient(
            WebConfigurationManager.AppSettings["customer_service_client_endpoint_name"]);

        try
        {
            program(client);

            client.Close();
        }
        catch
        {
            client.Abort();

            throw;
        }
    }
}
Default.aspx
<div>
    <table>
        <tr>
            <td>Customer Id</td>
            <td><asp:TextBox ID="txtCustomerId" runat="server" Width="120px"></asp:TextBox> </td>
            <td style="width:100px"></td>
            <td>Company Name</td>
            <td><asp:TextBox ID="txtCompanyName" runat="server" Width="250px"></asp:TextBox> </td>
        </tr>
        <tr>
            <td>Contact Name</td>
            <td><asp:TextBox ID="txtContactName" runat="server" Width="300px"></asp:TextBox> </td>
            <td></td>
            <td>Contact Title</td>
            <td><asp:TextBox ID="txtContactTitle" runat="server" Width="250px"></asp:TextBox> </td>
        </tr>
        <tr>
            <td rowspan="3">Address</td>
            <td rowspan="3"><asp:TextBox ID="txtAddress" runat="server" Width="300px" TextMode="MultiLine" Height="70px"></asp:TextBox> </td>
            <td rowspan="3"></td>
            <td>City</td>
            <td><asp:TextBox ID="txtCity" runat="server" Width="200px"></asp:TextBox> </td>
        </tr>
        <tr>
            <td>Region</td>
            <td><asp:TextBox ID="txtRegion" runat="server" Width="200px"></asp:TextBox> </td>
        </tr>
        <tr>
            <td>Country</td>
            <td><asp:TextBox ID="txtCountry" runat="server" Width="200px"></asp:TextBox> </td>
        </tr>
        <tr>
            <td>Phone No</td>
            <td><asp:TextBox ID="txtPhoneNo" runat="server" Width="200px"></asp:TextBox> </td>
            <td></td>
            <td>Fax No</td>
            <td><asp:TextBox ID="txtFax" runat="server" Width="200px"></asp:TextBox> </td>
        </tr>
        <tr>
            <td colspan="5" style="text-align:center">
                <asp:Button ID="btnSave" runat="server" Width="100px" Text="Save" onclick="btnSave_Click" />
                <asp:Button ID="btnClear" runat="server" Width="100px" Text="Clear" onclick="btnClear_Click" />
            </td>
        </tr>
        <tr>
            <td colspan="5">
                <asp:Label runat="server" ID="lblMessage" Text="" CssClass="Message"></asp:Label>
                <asp:HiddenField ID="hndCustomerId" runat="server" Value="" />
            </td>
        </tr>
    </table>
</div>
<div>
    <asp:GridView ID="grdViewCustomers" runat="server"
        AllowPaging="True" AutoGenerateColumns="False" TabIndex="1"
        DataKeyNames="CustomerID" Width="100%" BackColor="White" 
        CellPadding="3" BorderStyle="Solid" BorderWidth="1px" BorderColor="Black" 
        GridLines="Horizontal" OnRowDataBound="grdViewCustomers_RowDataBound" 
        OnPageIndexChanging="grdViewCustomers_PageIndexChanging"
        OnSelectedIndexChanging="grdViewCustomers_SelectedIndexChanging"
        OnRowDeleting="grdViewCustomers_RowDeleting">
        <Columns>
            <asp:CommandField ShowSelectButton="True" HeaderText="Select" />
            <asp:CommandField ShowDeleteButton="True" HeaderText="Delete" />
            <asp:BoundField DataField="CustomerID" HeaderText="Customer ID" />
            <asp:BoundField DataField="CompanyName" HeaderText="Company Name" />
            <asp:BoundField DataField="ContactName" HeaderText="Contact Name" />
            <asp:BoundField DataField="ContactTitle" HeaderText="Contact Title" />
            <asp:BoundField DataField="Address" HeaderText="Address" />
            <asp:BoundField DataField="City" HeaderText="City" />
            <asp:BoundField DataField="Region" HeaderText="Region" />
        </Columns>
        <RowStyle BackColor="White" ForeColor="#333333" />
        <FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
        <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Right" />
        <SelectedRowStyle BackColor="#A5D1DE" Font-Bold="true" ForeColor="#333333" />
        <HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
        <AlternatingRowStyle BackColor="#E2DED6" ForeColor="#284775" />
    </asp:GridView>
</div>
Default.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        ClearScreen();
        BindGrid();
    }
}
/// <summary>
/// Clearing the screen
/// </summary>
private void ClearScreen()
{
    txtCustomerId.Text = "";
    txtCompanyName.Text = "";
    txtContactName.Text = "";
    txtContactTitle.Text = "";
    txtAddress.Text = "";
    txtCity.Text = "";
    txtRegion.Text = "";
    txtCountry.Text = "";
    txtPhoneNo.Text = "";
    txtFax.Text = "";
    lblMessage.Text = "";
    hndCustomerId.Value = "";
}

protected void grdViewCustomers_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        e.Row.Cells[1].Attributes.Add("onclick", "return confirm('Are you sure want to delete?')");
    }
}

protected void grdViewCustomers_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
    grdViewCustomers.PageIndex = e.NewPageIndex;
    grdViewCustomers.SelectedIndex = -1;
    BindGrid();
}
protected void btnClear_Click(object sender, EventArgs e)
{
    ClearScreen();
}
protected void grdViewCustomers_SelectedIndexChanging(object sender, GridViewSelectEventArgs e)
{
    try
    {
        hndCustomerId.Value = grdViewCustomers.Rows[e.NewSelectedIndex].Cells[2].Text.Trim();
        if (hndCustomerId.Value.Length > 0)
        {
            CustomerServiceHelper helper = new CustomerServiceHelper();
            Customer customer = helper.Get(hndCustomerId.Value);

            txtCustomerId.Text = customer.CustomerID;
            txtCompanyName.Text = customer.CompanyName;
            txtContactName.Text = customer.ContactName;
            txtContactTitle.Text = customer.ContactTitle;
            txtAddress.Text = customer.Address;
            txtCity.Text = customer.City;
            txtRegion.Text = customer.Region;
            txtCountry.Text = customer.Country;
            txtPhoneNo.Text = customer.Phone;
            txtFax.Text = customer.Fax;
        }
    }
    catch (Exception ex)
    {
        lblMessage.Text = "There is an error occured while processing the request. Please verify the code!";
    }
}
protected void grdViewCustomers_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
    try
    {
        string strCustomerID = grdViewCustomers.Rows[e.RowIndex].Cells[2].Text.Trim();
        if (strCustomerID.Length > 0)
        {
            CustomerServiceHelper helper = new CustomerServiceHelper();
            helper.Delete(strCustomerID);

            ClearScreen();
            BindGrid();
            lblMessage.Text = "Record deleted successfully";
        }
    }
    catch (Exception ex)
    {
        lblMessage.Text = "There is an error occured while processing the request. Please verify the code!";
    }
}
protected void btnSave_Click(object sender, EventArgs e)
{
    try
    {
        Customer customer = new Customer();
        customer.CustomerID = txtCustomerId.Text;
        customer.CompanyName = txtCompanyName.Text;
        customer.ContactName = txtContactName.Text;
        customer.ContactTitle = txtContactTitle.Text;
        customer.Address = txtAddress.Text;
        customer.City = txtCity.Text;
        customer.Region = txtRegion.Text;
        customer.Country = txtCountry.Text;
        customer.Phone = txtPhoneNo.Text;
        customer.Fax = txtFax.Text;

        CustomerServiceHelper helper = new CustomerServiceHelper();
        helper.Save(customer, (hndCustomerId.Value.Trim().Length > 0));

        ClearScreen();
        BindGrid();
        lblMessage.Text = "Record saved successfully";
    }
    catch (Exception ex)
    {
        lblMessage.Text = "There is an error occured while processing the request. Please verify the code!";
    }
}
/// <summary>
/// Method which binds the data to the Grid
/// </summary>
private void BindGrid()
{
    try
    {
        CustomerServiceHelper helper = new CustomerServiceHelper();
        grdViewCustomers.DataSource = helper.GetAll();
        grdViewCustomers.DataBind();
    }
    catch (Exception e)
    {
        lblMessage.Text = "There is an error occured while processing the request. Please verify the code!";
    }
}
Web.Config
Modify or add the appSettings and system.serviceModel in the Web.Config as defined below.
<appSettings>
 <clear/>
 <add key="customer_service_client_endpoint_name" value="CustomerServiceClient"/>
</appSettings>
<system.serviceModel>
 <behaviors>
  <serviceBehaviors>
   <behavior name="WcfServices">
    <serviceMetadata httpGetEnabled="true"/>
    <serviceThrottling maxConcurrentCalls="100" maxConcurrentSessions="100"/>
   </behavior>
  </serviceBehaviors>
 </behaviors>
 <bindings>
  <wsHttpBinding>
   <binding name="wsHttpBinding_WcfServices" closeTimeout="10:10:00" openTimeout="10:10:00" receiveTimeout="10:10:00" sendTimeout="10:10:00" transactionFlow="true" maxReceivedMessageSize="2147483647">
    <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
   </binding>
  </wsHttpBinding>
 </bindings>
 <client>
  <endpoint address="http://localhost/DNT.WCFHost/CustomerService.svc" binding="wsHttpBinding" bindingConfiguration="wsHttpBinding_WcfServices" contract="ICustomerService" name="CustomerServiceClient"/>
 </client>
</system.serviceModel>
To add another service, add the endpoint in the <system.serviceModel><client> and add client class entry in <appSettings>.
EntityClient.cs, CustomerServiceHelper.cs
As explained before, to create those files use the svcutil utility. So open the Visual Studio Command Prompt and execute the svcutil as below -
svcutil.exe /language:cs /out:c:\client.cs /config:c:\config http://localhost/DNT.WCFHost/CustomerService.svc

The client class files are stored under C:\ drive. Open the client.cs file in Visual Studio and copy the Customer and DNTFaultException classes to EntityClient.cs with the namespace. ICustomerService, ICustomerServiceChannel interfaces and CustomerServiceClient class to CustomerServiceClient.cs file.

The reason to separate the entity class from the interface and the service client class is when the entity class referred in multiple services, the same entity class will be created multiple client class files. Repeating same class for multiple class will give error.

Run the project and see the output -













download the source code in C# here.

0 Responses to “Hosting WCF Services by extending SeviceHostingFactory - Part 2”

Post a Comment