Tuesday, January 22, 2008

Implementing WCF Service Part 2 - Client

I will consume the Customer WCF Service which I developed in Part 1 on WS* Http Binding, you can implement the best security, transactions and many more things using this way. However, I will consume in a very simplistic way in this post. I assume that you have already deployed the WCF Service under IIS and have a working URL ready to be referenced and you are planning to use the customer WCF service in ASPX web Page.

Create a Test Web Site Project using Visual Studio 2008/5 and focus on following 3 files

1.       Web.Config
2.       CustomerWcfServiceTest.aspx – The page you added for testing the WCF Service
3.       CustomerWcfServiceTest.aspmx.vb – Code behind file for WCF Service Test Page
Steps: Right Click on the project and click add the Customer WCF Service using Add Service Reference. Let’s say you give it a name called CustomerWcfService.
 
Web.Config
After adding the above service, verify the web.config file that binding and endpoint information is added to it. This information gets automatically added or removed when you add or remove a service reference. The address will vary as per your machine. You should be able to see like
 
<system.serviceModel>
   <bindings>
    <wsHttpBinding>
    <bindingname="WSHttpBinding_ICustomerService"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">
     <readerQuotasmaxDepth="32"maxStringContentLength="8192"maxArrayLength="16384"
      maxBytesPerRead="4096"maxNameTableCharCount="16384" />
     <reliableSessionordered="true"inactivityTimeout="00:10:00"
      enabled="false" />
     <securitymode="Message">
      <transportclientCredentialType="Windows"proxyCredentialType="None"
       realm="" />
      <messageclientCredentialType="Windows"negotiateServiceCredential="true"
       algorithmSuite="Default"establishSecurityContext="true" />
     </security>
    </binding>
   </wsHttpBinding>
</bindings>
<client>
   <endpointaddress="http://vishwa/ExampleService/CustomerService.svc"
    binding="wsHttpBinding"bindingConfiguration="WSHttpBinding_ICustomerService"
    contract="CustomerWcfService.ICustomerService"name="WSHttpBinding_ICustomerService">
    <identity>
     <dnsvalue="localhost" />
    </identity>
   </endpoint>   
</client>
 
</system.serviceModel>
Remember, you will be using binding Name WSHttpBinding_ICustomerService for consuming this service in code behind file.
 CustomerWCFServiceTest.aspx: Add the following code inside the body of this page
<form id="form1" runat="server">                
                <table>
                <tr>
                    <td colspan="2"><b>Through Server Side Service Reference</b></td>
                </tr>
                <tr>
                    <td >Customer ID :</td>
                    <td><asp:TextBox ID="txtCustID" runat="server" Text="12345"></asp:TextBox></td>
                </tr>     
                <tr>
                    <td>Customer Name :</td>
                <td>
                    <asp:TextBox ID="txtCustName" runat="server" Text="Joe Smith"></asp:TextBox>
                </td>
                </tr>
                <tr>
                    <td>Customer DOB (yyyy-mm-dd):</td>
                    <td><asp:TextBox ID="txtCustDOB" runat="server" Text="1988-08-08"></asp:TextBox></td>
                </tr>
               <tr>
                    <td>Customer Address:</td>
                    <td><asp:TextBox ID="txtCustAddress" runat="server" Text="unknown"></asp:TextBox></td>
                </tr>
                <tr>
                    <td><asp:Button ID="btnGetCustomer" runat="server" Text="Get Customer" /></td>
                    <td><asp:Button ID="btnAddCustomer" runat="server" Text="Add Customer" /></td>
                </tr>
                <tr>
                    <td><asp:Button ID="btnUpdateCustomer" runat="server" Text="Update Customer" /></td>
                    <td><asp:Button ID="btnDeleteCustomer" runat="server" Text="Delete Customer" /></td>
                </tr>
                <tr>
                    <td>
                    <asp:Button id="btnGetCustomers" runat="server" Text="Get All Customers"/></td>
                    <td><asp:Label ID="lblStatus" runat="server" Text="Status" 
                            ForeColor="#CC3300" style="font-weight: 700"></asp:Label></td>
                </tr>                
               </table>         
 
           </form>
            <br />
            <form id="frmCustomerS" method="post" action="CustomerWcfServiceTest.aspx">
            <div>    
                <table>
                <tr><td colspan="2"><b>Through Client Side SOAP/XML HTTP POST</b></td></tr>
                <tr><td>Customer ID :</td><td><input name="ID" id="ID" type="text" value="12345" /> </td></tr>
                <tr><td>Customer Name :</td><td><input name="Name" id="Name" type="text" value="Chris Clark" /> </td></tr>
                <tr><td>Customer DOB (yyyy-mm-dd):</td><td><input name="DOB" id="DOB" type="text" value="1988-08-08"/> </td></tr>
                <tr><td>Customer Address:</td><td><input name="Address" id="Address" type="text" value="unknown"/> </td></tr>
                 <tr>
                    <td><input type="button" name="btnGetCustomer" value="Get Customer" onclick="GetCustomerSOAP()" /></td>
                    <td><input type="button" name="btnAddCustomer" value="Add Customer" onclick="AddCustomerSOAP()" /></td>
                </tr>
                 <tr>
                    <td><input type="button" name="btnUpdateCustomer" value="Update Customer" onclick="UpdateCustomerSOAP()" /></td>
                    <td><input type="button" name="btnDeleteCustomer" value="Delete Customer" onclick="DeleteCustomerSOAP()"/></td>
                </tr>     
                <tr>
                    <td colspan="2"><input type="button" name="btnGetAllCustomers" value="Get All Customers" onclick="GetCustomersSOAP()"/></td>
                </tr>    
                </table>                
            </div>   
            </form>
CustomerWCFServiceTest.aspx.vb: Add the following code to handle the events
Partial Class CustomerServiceTest
   Inherits System.Web.UI.Page
 
   Protected Sub btnGetCustomer_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnGetCustomer.Click
       Dim wcfSrv As New CustomerWcfService.CustomerServiceClient("WSHttpBinding_ICustomerService")
       Dim cust As CustomerWcfService.Customer = wcfSrv.GetCustomer(CInt(Me.txtCustID.Text))
       If cust.ID > 0 Then
           Me.txtCustID.Text = cust.ID
           Me.txtCustName.Text = cust.Name
           Me.txtCustDOB.Text = cust.DOB
           Me.txtCustAddress.Text = cust.Address
           Me.lblStatus.Text = "Customer found."
       Else
           Me.lblStatus.Text = "Customer not found."
           Me.txtCustName.Text = ""
           Me.txtCustDOB.Text = ""
       End If
       wcfSrv.Close()
   End Sub
 
   Protected Sub btnAddCustomer_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAddCustomer.Click
       Dim wcfSrv As New CustomerWcfService.CustomerServiceClient("WSHttpBinding_ICustomerService")
       Dim cust As New CustomerWcfService.Customer
       cust.Name = Me.txtCustName.Text
       cust.DOB = CDate(Me.txtCustDOB.Text)
       cust.Address = Me.txtCustAddress.Text
       Dim rtn As Integer = wcfSrv.AddCustomer(cust)
       lblStatus.Text = "Cust ID: " & rtn.ToString
       wcfSrv.Close()
   End Sub
 
   Protected Sub btnUpdateCustomer_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnUpdateCustomer.Click
       Dim wcfSrv As New CustomerWcfService.CustomerServiceClient("WSHttpBinding_ICustomerService")
       Dim cust As New CustomerWcfService.Customer
       cust.ID = CInt(Me.txtCustID.Text)
       cust.Name = Me.txtCustName.Text
       cust.DOB = CDate(Me.txtCustDOB.Text)
       cust.Address = Me.txtCustAddress.Text
       Dim rtn As Boolean = wcfSrv.UpdateCustomer(cust)
       lblStatus.Text = "Update Status is : " & rtn.ToString
       wcfSrv.Close()
   End Sub
 
   Protected Sub btnDeleteCustomer_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnDeleteCustomer.Click
       Dim wcfSrv As New CustomerWcfService.CustomerServiceClient("WSHttpBinding_ICustomerService")
       Dim rtn As Boolean = wcfSrv.DeleteCustomer(CInt(Me.txtCustID.Text))
       lblStatus.Text = "Delete Status is : " & rtn.ToString
       wcfSrv.Close()
   End Sub
 
   Protected Sub btnGetCustomers_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnGetCustomers.Click
       Dim wcfSrv As New CustomerWcfService.CustomerServiceClient("WSHttpBinding_ICustomerService")
       Dim custArr() As CustomerWcfService.Customer
       custArr = wcfSrv.GetCustomers()
 
       For Each cust As CustomerWcfService.Customer In custArr
           Response.Write("ID: " & cust.ID.ToString & " Name: " & cust.Name & "<br/>")
       Next
       lblStatus.Text = "No of Customer Records found: " & custArr.Length.ToString
       wcfSrv.Close()
   End Sub
 
 
End Class
 
You are done. Run the project and test the page, you should be able to Add, Modify, Delete and Get Customer records.

 

Implementing WCF Service Part 1 - Service

You must be wondering, that in WCF era ASMX Web Service! I wrote the first one 5 years ago and now trying to move them to WCF Service, but lot of companies have not even adopted the web service and some have only started adopting it recently, and now they realized that a new era has come. I will discuss my experiments & experiences with WCF in later posts. However, I would like to post a simple Customer ASMX Web Service and then consume it by a ASP.NET Web Page via Server Side and then Client Side using direct SOAP based XML through HTTP Post. Later, I will create a similar WCF Service with exactly same methods and will access the data exactly same way. Remember this is not a simple HelloWorld Example, this Web Service deals with primitive data type as well as complex one. How far you would like to dive deep into it, will be up to you.

          In order to keep the example sweet and simple and close to real world, I will be using a Customers XML data file and will perform CRUD operations.  I created this project using Visual Studio 2008 and wrote code using VB.NET.

           You can also use Visual Studio 2005 for this project.

This project basically contains 5 file, you can create them in following order.
1.       Web.Config
2.       Customer.vb - Customer class
3.       ServiceHelper.VB – Collection of CRUD Methods
4.       CustomerWebService.asmx – ASMX Web Service Page
5.       CustomerWebService.asmx.vb – Code behind file of the .asmx file
 
My Project Name is – Vishwa.Example.WebService
 
Web.Config
If you are planning to deploy this web service for HTTP GET and POST uses, add the following lines under <system.web> section. By default they will only work if you are running locally.
<webServices>
           <protocols>
                     <add name="HttpPost" />
                     <add name="HttpGet" />
            </protocols>
</webServices>
 
Customer.vb - Add this class in your project with following code. This class is a Data Transfer Object.
Namespace Example.WebService
    Public Class Customer
 
        <System.Xml.Serialization.XmlElement(ElementName:="ID", Order:=0)> _
        Public CustID As Integer = 0
 
        <System.Xml.Serialization.XmlElement(ElementName:="Name", Order:=1)> _
        Public CustName As String = String.Empty
 
        <System.Xml.Serialization.XmlElement(ElementName:="DOB", Order:=2)> _
        Public CustDOB As DateTime = DateTime.MinValue
 
        <System.Xml.Serialization.XmlElement(ElementName:="Address", Order:=3)> _
        Public CustAddress As String = String.Empty
 
        <System.Xml.Serialization.XmlElement(ElementName:="DateCreated", Order:=4)> _
        Public DateCreated As DateTime = DateTime.Now
 
 
        <System.Xml.Serialization.XmlElement(ElementName:="DateModified", Order:=5)> _
        Public DateModified As DateTime = DateTime.Now
 
        Public Sub New()
 
        End Sub
 
    End Class
End Namespace
ServiceHelper.vb - Add this class now with following code. Please note that I am using a Customer Business Object, which I created in my earlier post.
 
Imports Vishwa.Example.Business
 
Namespace Example.WebService
    Public NotInheritable Class ServiceHelper
 
        Private Shared instance As New ServiceHelper
        Private Shared  bizObj As New CustomerBiz
        Private Sub New()
 
        EndSub
 
        Friend Shared Function GetCustomerData(ByVal ID AsInteger) As Customer
            Dim bizCustomer As CustomerBiz = Nothing
            bizCustomer = bizObj.GetCustomer(ID)
            Return GetCustomerDataFromBizCustomer(bizCustomer)
        End Function
 
        Friend Shared Function GetCustomersData() As List(Of Customer)
            Dim customers AsNew List(Of Customer)
            Dim bizCustomers AsNew List(Of CustomerBiz)
            bizCustomers = bizObj.GetCustomers()
 
            ForEach bizCustRec As CustomerBiz In bizCustomers
                customers.Add(GetCustomerDataFromBizCustomer(bizCustRec))
            Next
            Return customers
 
        End Function
 
        Friend Shared Function AddCustomerData(ByVal custRecord As Customer) As Integer
            Return bizObj.AddCustomer(custRecord.CustName, custRecord.CustDOB, custRecord.CustAddress)
        End Function
 
        Friend Shared Function UpdateCustomerData(ByVal custRecord As Customer) As Boolean
            Return bizObj.UpdateCustomer(custRecord.CustID, custRecord.CustName, custRecord.CustDOB, custRecord.CustAddress)
        End Function
 
        Friend Shared Function DeleteCustomerData(ByVal ID AsInteger) As Boolean
            Return bizObj.DeleteCustomer(ID)
        End Function
 
        Private Shared Function GetCustomerDataFromBizCustomer(ByVal bizCust As CustomerBiz) As Customer
            Dim custRecord AsNew Customer
            If Not bizCust Is Nothing AndAlso bizCust.CustID > 0 Then
                custRecord.CustID = bizCust.CustID
                custRecord.CustName = bizCust.CustName
                custRecord.CustDOB = bizCust.CustDOB
                custRecord.CustAddress = bizCust.CustAddress
                custRecord.DateCreated = bizCust.DateCreated
                custRecord.DateModified = bizCust.DateModified
            End If
            Return custRecord
        End Function
 
    End Class
End Namespace
 CustomerWebService.asmx – Add this ASMX file, a Code behind will be added by default. The markup inside CustomerWebService.asmx will looks like
<%@ WebService Language="VB" CodeBehind="CustomerWebService.asmx.vb" Class="Vishwa.Example.WebService.CustomerWebService" %>
  
 
CustomerWebService.asmx.vb Add following code in this file
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.ComponentModel
 
Namespace Example.WebService
    <System.Web.Script.Services.ScriptService()> _
    <System.Web.Services.WebService(Name:="CustomerWebService", Namespace:="http://webservices.vishwamohan.net", _
                                    Description:="Customer ASMX Web Service.")> _
    <System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
    <ToolboxItem(False)> _
    Public Class CustomerWebService
        Inherits System.Web.Services.WebService
 
        <WebMethod(Description:="Gets a customer record on customer ID.")> _
        Public Function GetCustomer(ByVal ID As Integer) As Customer
            Return ServiceHelper.GetCustomerData(ID)
        End Function
 
        <WebMethod(Description:="Gets all customer record.")> _
        Public Function GetCustomers() As List(Of Customer)
            Return ServiceHelper.GetCustomersData()
        End Function
 
        <WebMethod(Description:="Adds a customer record and returns customer ID.")> _
        Public Function AddCustomer(ByVal CustomerRecord As Customer) As Integer
            Return ServiceHelper.AddCustomerData(CustomerRecord)
        End Function
 
        <WebMethod(Description:="Deletes a customer record on customer ID.")> _
        Public Function DeleteCustomer(ByVal ID As Integer) As Boolean
            Return ServiceHelper.DeleteCustomerData(ID)
        End Function
 
        <WebMethod(Description:="Updates a customer record.")> _
        Public Function UpdateCustomer(ByVal CustomerRecord As Customer) As Boolean
            Return ServiceHelper.UpdateCustomerData(CustomerRecord)
        End Function
    End Class
End Namespace
You are done!
Now you compile the project and run. You should be able to see following 5 web methods.
In next post I will consume these methods through a web page via direct web service integration in project as well as through SOAP XML HTTP Post.