This post will focus on implementing POX (Plain Old XML) and REST (Representational State Transfer) in WCF. In other words this is an implementation of the old HTTP XML Post. I spent not several hours but several days to figure out the solution. As all of you know making HTTP GET is easy in WCF but HTTP Post (without using SOAP) is a different story. I researched all around the web but nowhere found a simple example for this option, yes not even on Microsoft site. Many people just post their opinion in few lines and then you keep guessing, and if you are new to this then keep doing trial and error method for hours and days provided you keep your patience on. Once you will find the solution, it will look so easy.
So, In order to make this happen, we will have to make changes at following places
1. Web.Config – Both at Service and Client side for new binding2. ICustomerService.vb3. CustomerService.svc.vb4. CustomerWcfServiceTest.aspx – For adding new HTML form fields and JavaScript functions
So let’s see step by step what we need to make change in each file.Web.Config (WCF Service) – Add the following in respective sectionsWeb.Config (WCF Client or WebSite) : Once you made the above change in your service Config file, you can update your service reference in client application or web site.When you click on update Web/Service references, It will automatically add the following sections in respective area, if not make sure that you add it in client web site Web.config file.<customBinding><binding name="WebHttpBinding_ICustomerService">
<textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"messageVersion="Soap12" writeEncoding="utf-8"><readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"maxBytesPerRead="4096" maxNameTableCharCount="16384" /></textMessageEncoding></binding></customBinding><endpoint address="http://vishwa/ExampleService/CustomerService.svc/pox"
binding="customBinding" bindingConfiguration="WebHttpBinding_ICustomerService"contract="CustomerWcfService.ICustomerService" name="WebHttpBinding_ICustomerService" />ICustomerService.vb: First we need to modify the Service Contract, you can use the existing methods for implementing HTTP GET, but for HTTP POST, you will need separate interface. Replace the existing code of this file with following codeImports System.ServiceModel.Web
Namespace Example.WcfService
<ServiceContract(Name:="ICustomerService", NameSpace:="http://wcfservices.vishwamohan.net")> _Public Interface ICustomerService'Implementing HTTP GET using WebGet()
<OperationContract(Name:="GetCustomer"), WebGet()> _
Function GetCustomer(ByVal ID As Integer) As Customer<OperationContract(Name:="GetCustomers"), WebGet()> _
Function GetCustomers() As List(Of Customer)<OperationContract(Name:="AddCustomer")> _
Function AddCustomer(ByVal CustomerRecord As Customer) As Integer<OperationContract(Name:="UpdateCustomer")> _
Function UpdateCustomer(ByVal CustomerRecord As Customer) As Boolean<OperationContract(Name:="DeleteCustomer")> _
Function DeleteCustomer(ByVal ID As Integer) As Boolean'Implementing POX/REST - HTTP POST
<OperationContract(Name:="GetCustomerByPOX"), _
WebInvoke(Method:="POST", BodyStyle:=WebMessageBodyStyle.Bare, _
RequestFormat:=WebMessageFormat.Xml, ResponseFormat:=WebMessageFormat.Xml)> _Function GetCustomerByPOX(ByVal XMLString As System.Xml.XmlElement) As Customer<OperationContract(Name:="GetCustomersByPOX"), WebInvoke(Method:="POST", _BodyStyle:=WebMessageBodyStyle.Bare, _RequestFormat:=WebMessageFormat.Xml, _ResponseFormat:=WebMessageFormat.Xml)> _Function GetCustomersByPOX() As List(Of Customer)<OperationContract(Name:="AddCustomerByPOX"), WebInvoke(Method:="POST", _BodyStyle:=WebMessageBodyStyle.Bare, _RequestFormat:=WebMessageFormat.Xml, _ResponseFormat:=WebMessageFormat.Xml)> _Function AddCustomerByPOX(ByVal RequestXML As System.Xml.XmlElement) As Integer<OperationContract(Name:="UpdateCustomerByPOX"), WebInvoke(Method:="POST", _BodyStyle:=WebMessageBodyStyle.Bare, _RequestFormat:=WebMessageFormat.Xml, _ResponseFormat:=WebMessageFormat.Xml)> _Function UpdateCustomerByPOX(ByVal RequestXML As System.Xml.XmlElement) As Boolean<OperationContract(Name:="DeleteCustomerByPOX"), _
WebInvoke(Method:="POST", BodyStyle:=WebMessageBodyStyle.Bare, _
RequestFormat:=WebMessageFormat.Xml, ResponseFormat:=WebMessageFormat.Xml)> _Function DeleteCustomerByPOX(ByVal XMLString As System.Xml.XmlElement) As BooleanEnd InterfaceEnd Namespace
CustomerService.svc.vb: Once the service contracts are implemented, now we need these methods to be added to actual service page to accept the request and send the response. Add the following code.Public Function GetCustomerByPOX(ByVal RequestXML As System.Xml.XmlElement) As Customer Implements ICustomerService.GetCustomerByPOX Dim custID As Integer = 0 If Not RequestXML.Item("ID") Is Nothing AndAlso IsNumeric(RequestXML.Item("ID").InnerText) Then custID = CInt(RequestXML.Item("ID").InnerText) End If Return ServiceHelper.GetCustomerData(custID) End Function Public Function AddCustomerByPOX(ByVal RequestXML As System.Xml.XmlElement) As IntegerImplements ICustomerService.AddCustomerByPOX
Dim returnID As Integer = 0If Not RequestXML.Item("CustomerRecord") Is Nothing ThenDim customerRecord As New CustomerIf Not RequestXML.Item("CustomerRecord").Item("ID") Is Nothing AndAlso _IsNumeric(RequestXML.Item("CustomerRecord").Item("ID").InnerText) ThencustomerRecord.CustID = CInt(RequestXML.Item("CustomerRecord").Item("ID").InnerText)End IfIf Not RequestXML.Item("CustomerRecord").Item("Name") Is Nothing Then _customerRecord.CustName = RequestXML.Item("CustomerRecord").Item("Name").InnerTextIf Not RequestXML.Item("CustomerRecord").Item("DOB") Is Nothing AndAlso _IsDate(RequestXML.Item("CustomerRecord").Item("DOB").InnerText) ThencustomerRecord.CustDOB = CDate(RequestXML.Item("CustomerRecord").Item("DOB").InnerText)End IfIf Not RequestXML.Item("CustomerRecord").Item("Address") Is Nothing Then _customerRecord.CustAddress = RequestXML.Item("CustomerRecord").Item("Address").InnerTextreturnID = ServiceHelper.AddCustomerData(customerRecord)End IfReturn returnID
End FunctionPublic Function GetCustomersByPOX() As System.Collections.Generic.List(Of Customer) Implements ICustomerService.GetCustomersByPOX Return ServiceHelper.GetCustomersData() End Function Public Function UpdateCustomerByPOX(ByVal RequestXML As System.Xml.XmlElement) As Boolean Implements ICustomerService.UpdateCustomerByPOX Dim returnValue As Boolean = False If Not RequestXML.Item("CustomerRecord") Is Nothing Then Dim customerRecord As New Customer If Not RequestXML.Item("CustomerRecord").Item("ID") Is Nothing AndAlso _ IsNumeric(RequestXML.Item("CustomerRecord").Item("ID").InnerText) Then customerRecord.CustID = CInt(RequestXML.Item("CustomerRecord").Item("ID").InnerText) End If If Not RequestXML.Item("CustomerRecord").Item("Name") Is Nothing Then _ customerRecord.CustName = RequestXML.Item("CustomerRecord").Item("Name").InnerText If Not RequestXML.Item("CustomerRecord").Item("DOB") Is Nothing AndAlso _ IsDate(RequestXML.Item("CustomerRecord").Item("DOB").InnerText) Then customerRecord.CustDOB = CDate(RequestXML.Item("CustomerRecord").Item("DOB").InnerText) End If If Not RequestXML.Item("CustomerRecord").Item("Address") Is Nothing Then _ customerRecord.CustAddress = RequestXML.Item("CustomerRecord").Item("Address").InnerText returnValue = ServiceHelper.UpdateCustomerData(customerRecord) End If Return returnValue End Function Public Function DeleteCustomerByPOX(ByVal RequestXML As System.Xml.XmlElement) As Boolean Implements ICustomerService.DeleteCustomerByPOX Dim custID As Integer = 0 Dim returnValue As Boolean = False If Not RequestXML.Item("ID") Is Nothing AndAlso IsNumeric(RequestXML.Item("ID").InnerText) Then custID = CInt(RequestXML.Item("ID").InnerText) returnValue = ServiceHelper.DeleteCustomerData(custID) End If Return returnValue End FunctionNow you are done from service side. Compile the project and deploy to the same place where you did before.CustomerWcfServiceTest.aspx: Now I am back to same old page in which I tested earlier posts. This time I will add following HTML code and JavaScript inside body tag. This will allow you use simple XML for transaction without SOAP.<form id="frmCustomerGet1" method="get" action="http://vishwa/exampleservice/customerservice.svc/pox/GetCustomer"><table><tr><td colspan="2"><b>Through Client Side HTML Form HTTP GET</b></td></tr><tr><td>Customer ID :</td><td><input name="ID" type="text" value="969225896" /> </td></tr><tr><td colspan="2"><input type="submit" name="btnGetCustomer" value="Get a Customer"/></td></tr></table></form><form id="frmCustomerGet2" method="get" action="http://vishwa/exampleservice/customerservice.svc/pox/GetCustomers"><div><input type="submit" name="btnGetAllCustomers" value="Get All Customers"/></div></form><br /><form id="frmCustomerPost1" method="post" action="http://vishwa/exampleservice/customerservice.svc/pox"><table><tr><td colspan="2"><b>Through Client Side Plain Old XML (POX) HTTP POST</b></td></tr>
<tr><td>Customer ID :</td><td><input name="ID" type="text" value="969225896" /> </td></tr><tr><td>Customer Name :</td><td><input name="Name" type="text" value="Chris Clark" /> </td></tr><tr><td>Customer DOB (yyyy-mm-dd):</td><td><input name="DOB" type="text" value="1980-08-08"/> </td></tr><tr><td>Customer Address :</td><td><input name="Address" type="text" value="unknown"/> </td></tr><tr><td><input type="button" name="btnGetCustomer" value="Get Customer" onclick="GetCustomerByPOX()" /></td><td><input type="button" name="btnAddCustomer" value="Add Customer" onclick="AddCustomerByPOX()" /></td></tr><tr><td><input type="button" name="btnUpdateCustomer" value="Update Customer" onclick="UpdateCustomerByPOX()" /></td><td><input type="button" name="btnDeleteCustomer" value="Delete Customer" onclick="DeleteCustomerByPOX()"/></td></tr><tr><td colspan="2"><input type="button" name="btnGetAllCustomers" value="Get All Customers" onclick="GetCustomersByPOX()"/></td></tr></table></form>Add Following JavaScript in the page<script type="text/javascript" language="javascript">function GetCustomerByPOX()
{var dataText = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";dataText += "<GetCustomer><ID>" + frmCustomerPost1.ID.value + "</ID>";dataText += "</GetCustomer>";
alert(dataText);urlToPost = "http://vishwa/exampleservice/customerservice.svc/pox/GetCustomerByPOX"
var xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");xmlHttp.open("POST", urlToPost,false);xmlHttp.setRequestHeader("Content-Type", "text/xml");xmlHttp.send(dataText);alert(xmlHttp.responseText);}function AddCustomerByPOX()
{var dataText = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";dataText += "<AddCustomer><CustomerRecord>";
dataText += "<ID>" + frmCustomerPost1.ID.value + "</ID>";dataText += "<Name>" + frmCustomerPost1.Name.value + "</Name>";dataText += "<DOB>" + frmCustomerPost1.DOB.value + "</DOB>";dataText += "<Address>" + frmCustomerPost1.Address.value + "</Address>";dataText += "</CustomerRecord></AddCustomer>";
alert(dataText);urlToPost = "http://vishwa/exampleservice/customerservice.svc/pox/AddCustomerByPOX"
var xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");xmlHttp.open("POST", urlToPost,false);xmlHttp.setRequestHeader("Content-Type", "text/xml");xmlHttp.send(dataText);alert(xmlHttp.responseText);}function UpdateCustomerByPOX()
{var dataText = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";dataText += "<UpdateCustomer><CustomerRecord>";
dataText += "<ID>" + frmCustomerPost1.ID.value + "</ID>";dataText += "<Name>" + frmCustomerPost1.Name.value + "</Name>";dataText += "<DOB>" + frmCustomerPost1.DOB.value + "</DOB>";dataText += "<Address>" + frmCustomerPost1.Address.value + "</Address>";dataText += "</CustomerRecord></UpdateCustomer>";
alert(dataText);urlToPost = "http://vishwa/exampleservice/customerservice.svc/pox/UpdateCustomerByPOX"
var xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");xmlHttp.open("POST", urlToPost,false);xmlHttp.setRequestHeader("Content-Type", "text/xml");xmlHttp.send(dataText);alert(xmlHttp.responseText);}function DeleteCustomerByPOX()
{var dataText = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";dataText += "<DeleteCustomer><ID>" + frmCustomerPost1.ID.value + "</ID>";dataText += "</DeleteCustomer>";
alert(dataText);urlToPost = "http://vishwa/exampleservice/customerservice.svc/pox/DeleteCustomerByPOX"
var xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");xmlHttp.open("POST", urlToPost,false);xmlHttp.setRequestHeader("Content-Type", "text/xml");xmlHttp.send(dataText);alert(xmlHttp.responseText);}function GetCustomersByPOX()
{urlToPost = "http://vishwa/exampleservice/customerservice.svc/pox/GetCustomersByPOX"
var xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");xmlHttp.open("POST", urlToPost,false);xmlHttp.setRequestHeader("Content-Type", "text/xml");xmlHttp.send(null);alert(xmlHttp.responseText);}</script>So, now you are ready to run this page and click the button you like by filling appropriate data. You should be able to see the transaction request and response in form of plain XML as alert.I believe, if you are integrating with an outside customer you will most likely choose WSHttpBinding, BasicHttpBinding or WebHttpBinding in the order of high to lower interoperability and security preference. Either one you choose performance wise it will be always lower than NetTcpBinding , NetMsmqBinding or NetNamedPipeBinding. However, Net* bindings will only work .NET consumers. If you wish to have best performance then you will have to choose NetNamedPipeBinding but this will require you to have the Service and Consumer on the same machine, if both are on the same network, use NetTcpBinding.
No comments:
Post a Comment