Click here to Skip to main content
15,868,016 members
Articles / Web Development / ASP.NET

WCF: From a Beginner's perspective and a tutorial - Sequel

Rate me:
Please Sign up or sign in to vote.
4.77/5 (8 votes)
2 Apr 2013CPOL11 min read 30.8K   590   25   11
This article gives a tutorial on consuming WCF service in ASP.NET web site and to create AJAX enabled WCF Service.

Introduction

Well, this very article is in continuance with my previous article on WCF. Folks can view the earlier article by browsing over to the URL: http://www.codeproject.com/Articles/566691/WCF-From-a-Beginners-perspective-a-Tutorial.

In this article I would want to explain and show how to consume a WCF service in an ASP.NET web application, and how to code a ASP.NET AJAX WCF service via codes and lots of illustrations.

Viewers and readers who don't have much idea as to what is WCF, what it does and else, kindly visit the above listed URL, it gives an initial understanding of the subject, as to how to start, how to proceed with coding WCF services and stuffs. Let's get started without further delay. Stay tuned. 

Background

There ain't specific background as such, but since this is a sequel to the above mentioned article (visit URL), I suggest a glance at that wouldn't do any harm. And yes, presence of Visual Studio 2008 is a pre-requisite.

Using the code

Let's start with the code part.

  1. Open your Visual Studio 2008 client, and click on New>Web Site.
  2. Image 1

  3. It will open a dialog box as shown below. Select WCF service from the template, give the location where you want to store the WCF service and then click OK.
  4. Image 2

  5. Visual Studio will open up a new solution. The solution will have one project WCF service project. Under App_Code folder, you can find two class files namely Service.cs and IService.cs. Also, Service.svc file would be evident. There will be some default implementation in the class files. Please delete them as per now, we will code our own functionalities.
  6. Image 3

  7. Let me give an idea as to what are we gonna do in this service. I am pretty fond of TV Series, hence this WCF service will help us to enter the details of our favorite TV series and will also assist us in viewing the details of them, once entered. I have two operations in my ServiceContract under IService.cs, namely InsertSeriesDetails() and GetSeriesDetails(). In my DataContract, I have three properties as DataMembers, since these will be serialized, when WCF service is consumed. Insertion of TV series details and then retrieval of those details will take place via a database. So let's create a table in a DB in SQL Server 2008.
  8. Open your SQL Management Studio, connect to your server, then create a table called as dbo.TVSeries in your desired database. For the time being I have 3 columns in the table, namely TVSeriesName, FavMaleCharacter, FavFemaleCharacter. You can have more columns as you desire. Copy the below SQL script and execute it in your SQL Management Studio.
  9. SQL
    CREATE TABLE dbo.TVSeries(
     
    [TVSeriesName] VARCHAR(max) NOT NULL,
    [FavMaleChar] VARCHAR(max) NOT NULL,
    [FavFemaleChar] VARCHAR(max) NOT NULL)

    Execute the script and you will find it evident under Tables category in your desired database as below:

    Image 4

    We will not insert rows into the table now, we will do it via an ASP.NET web site.

  10. Let's head back on creation of the WCF service. Start coding in your IService.cs file as shown below: 
    C#
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
    using System.Data;
     
    [ServiceContract]
    public interface IService
    {
    	[OperationContract]
    	string InsertSeriesDetails(TVSeries tvSeriesObj);
    	[OperationContract]
    	List<TVSeries> GetSeriesDetails();
    }
     
    [DataContract]
    public class TVSeries
    {
        
        string seriesName = "";
        string favMaleChar = "";
        string favFemaleChar = "";
        [DataMember]
        public string TVSeriesName 
        {
            get {return seriesName ;}
            set { seriesName=value;}
        }
        [DataMember]
        public string FavMaleCharacter 
        {
            get {return favMaleChar ;}
            set {favMaleChar=value ;}
        }
        [DataMember]
        public string FavFemaleCharacter  
        {
            get {return favFemaleChar ;}
            set { favFemaleChar=value;} 
        }
    }

    I would like to explain as to what I have coded in the IService.cs file. Here I have an interface as a Service Contract, which encompasses 2 Operation Contracts within itself, i.e., in plain words we can say that it has 2 methods defined under itself. Next, we have a user-defined class called as TVSeries having three DataMembers, which explains to the client that what kind of data it contains. After coding the IService.cs file, we will have to write the functionalities of the methods in Service.cs file. Let's get ahead with that.

  11. Copy the below shown code into your Service.cs file:
  12. C#
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
    using System.Configuration;
    using System.Data.SqlClient;
    using System.Data;
     
    public class Service : IService
    {
       SqlConnection xconn = new SqlConnection(
         ConfigurationManager.ConnectionStrings["connectionStrings"].ToString());
       public string InsertSeriesDetails(TVSeries tvSeriesObj)
        {
            string msg = string.Empty;
            SqlCommand xcmd = new SqlCommand("Insert into Development.dbo.TVSeries(
              TVSeriesName,FavMaleChar,FavFemaleChar) values(@seriesName,@favMale,@favFemale)", xconn);
            
            xcmd.Parameters.AddWithValue("@seriesName", tvSeriesObj.TVSeriesName);
            xcmd.Parameters.AddWithValue("@favMale", tvSeriesObj.FavMaleCharacter);
            xcmd.Parameters.AddWithValue("@favFemale", tvSeriesObj.FavFemaleCharacter);
            try
            {
                xconn.Open();
                int ret = xcmd.ExecuteNonQuery();
                if (ret == 1)
                {
                    msg = "Hurray...You have now entered your favorite TV Series Details..";
                }
                else
                {
                    msg = "Some error occurred..Please try again";
                }
            }
            finally
            {
                xconn.Close();
            }
            return msg;
            
        }
        public List<TVSeries> GetSeriesDetails()
        {
            
            List<TVSeries> TVlist = new List<TVSeries>();
            SqlDataAdapter da = new SqlDataAdapter("select * from Development.dbo.TVSeries", xconn);
            DataTable dt = new DataTable();
            
            try
            {
                xconn.Open();
                da.Fill(dt);
                if (dt.Rows.Count > 0)
                {
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        TVSeries obj = new TVSeries();
                        obj.TVSeriesName = dt.Rows[i][0].ToString();
                        obj.FavMaleCharacter = dt.Rows[i][1].ToString();
                        obj.FavFemaleCharacter = dt.Rows[i][2].ToString();
                        TVlist.Add(obj);
                    }
                }
            }
            finally
            {
                xconn.Close();
            }
            
            return TVlist;
        }
    }

    In the above code, we are trying to establish a connection with the SQL database under which our table resides, then we have the implementation of the two operation contracts, namely InsertSeriesDetails() and GetSeriesDetails(). InsertSeriesDetails() takes the class TVSeries as its argument, then we define a SQLCommand object,giving an appropriate Insert Query and then call the ExecuteNonQuery() method, to insert a row into the DB. GetSeriesDetails() involves a SQLDataAdapter, which fills a DataTable with the records from the SQL table, and then later we bind the results to a List.

     I would like to point out at this point of time that, we can't use a DataTable directly to bind the data when we use a WCF service. This very point will be discussed later in the article. Do watch for that.

    I personally like to segregate the connection strings in the configuration file, rather than using the big connection string in the code-behind file itself. You can define the connection string as below:

    XML
    <connectionStrings>
        <add name="connectionStrings" connectionString="Data Source=DEVELOPER-PC;Initial Catalog=Development;
          Integrated Security=true" providerName="System.Data.SqlClient"/>
    </connectionStrings>

    Also, an important part of the Config file would be the end-point configuration, for the time being I haven't messed up with the end points here, have left them to be default. I have wsHttpBinding in the config file, you can alter if you want to.

    XML
    <endpoint address="" binding="wsHttpBinding" contract="IService"> 

    Now, the WCF service is ready, right click the Service.svc file and select and click 'View in Browser', the ASP.NET Development server will open your browser and you can see your WCF service over there, something like below:

    Image 5

    Here you go, your service is up and running. Now let's create an ASP.NET website which will act as a client to consume this WCF service.

  13. You can create a new solution or add another project in the above solution. as you desire. Next. click on New>WebSite.
  14. Image 6

  15. A dialog box will open suggesting a lot of templates, click on ASP.NET Web Site, give the storage location and hit OK.
  16. Image 7

  17. An empty website will be added to your solution. Refer to the attached zipped code on designing the page. Basically I have 3 textboxes, in which the user will enter the tv series name, his fav male and female character names, 2 buttons namely 'Insert' and 'Click to see the details' and 1 grid view. It looks something like below:
  18. Image 8

    I have just given a lil bit design to the page using some CSS tricks and tips. You can find those stuffs in the StyleSheet.css page. Nevamind, let's move ahead.. Smile | <img src=

  19. Now comes the important part, adding the service reference to the web site. Right-click the web site project and click on 'Add Service Reference'. It will open a dialog box, where you will have to enter the URL of the service which you have just created, and hit Go. The ASP.NET engine lists all the operations which are exposed by the WCF service, you need to provide a namespace and hit OK. See the image below for further reference.
  20. Image 10

  21. Now, open the Default.aspx.cs file and type in the code as below:
  22. C#
    using System;
    using System.Configuration;
    using System.Data;
    using System.Linq;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Xml.Linq;
    using TV;
    using System.Collections.Generic;
    public partial class _Default : System.Web.UI.Page 
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            lblResult.Visible = false;
        }
        protected void Button1_Click(object sender, EventArgs e)
        {
            if (!(string.IsNullOrEmpty(txtSeriesName.Text) && 
               string.IsNullOrEmpty(txtMale.Text) && string.IsNullOrEmpty(txtFemale.Text)))
            {
                ServiceClient obj = new ServiceClient();
                TVSeries obj2 = new TVSeries();
                obj2.TVSeriesName = txtSeriesName.Text;
                obj2.FavMaleCharacter = txtMale.Text;
                obj2.FavFemaleCharacter = txtFemale.Text;
                string message = obj.InsertSeriesDetails(obj2);
                lblResult.Visible = true;
                lblResult.Text = message;
            }
            else
            {
                lblResult.Visible = true;
                lblResult.Text = "Please enter the TV series details..Then hit Insert button...";
                txtSeriesName.Focus();
            }
        }
        protected void Button2_Click(object sender, EventArgs e)
        {
            lblResult.Visible = false;
            ServiceClient obj3 = new ServiceClient();
            IList<TVSeries> listTV = obj3.GetSeriesDetails();
            grdView.DataSource = listTV;
            grdView.DataBind();
            
        }
    }

    Nothing special in the above code, we have just made an object of the proxy class created, ServiceClient and using that object we are calling the two exposed operations by the WCF service, on the 2 button clicks. Build the code, it should build without errors.

    Also, check the config file of the website for the client endpoint details, should be similar to something like below:

    XML
    <client>
       <endpoint address="http://localhost:51861/NewService/Service.svc"
        binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService"
        contract="TV.IService" name="WSHttpBinding_IService">
        <identity>
         <dns value="localhost" />
        </identity>
       </endpoint>
    </client> 
  23. Debug the solution, it shouldn't throw any errors as such and the functionalities should work as desired. Have a look below:
  24. Image 11

    Image 12

  25. I would like to stress on an important aspect over here, while consuming the WCF service, you might encounter an exception such as:
  26. {"The server was unable to process the request due to an internal error.
    For more information about the error, either turn on IncludeExceptionDetailInFaults 
      (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) 
      on the server in order to send the exception information back to the client, or turn on tracing 
      as per the Microsoft .NET Framework 3.0 SDK documentation and inspect the server trace logs."}

    It suggests that something is wrong in your WCF service, an exception is unhandled. We need to get to the root cause as to what's wrong in the code or else. For this we include the attribute includeExceptionDetailInFaults=true in the config file of the WCF service, in order to get ample information on the unhandled exception or error, which is sent back to the client. Have a look below:

    XML
    <serviceBehaviors>
    <behavior name="ServiceBehavior">
      <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
      <serviceMetadata httpGetEnabled="true"/>
      <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
      <serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true"/>
    </behavior>
    </serviceBehaviors>

    In my case, column names were not matching in the WCF service code and my DB, hence I too was getting the above enormous exception. I included the above said attribute and I was able to get hold of my error and ultimately resolve it. See the below image for further reference.

    Image 13

Hope the readers have got an idea as to how to consume a WCF service in an ASP.NET web application. Next, let's focus on how to code an AJAX enabled WCF service. Stay tuned.

An excerpt from MSDN is below:

ASP.NET AJAX consists of client-script libraries and of server components that are integrated to provide a robust development framework. To access a service from an ASP.NET page: once the service URL is added to the ASP.NET Script Manager control on the page, service operations may be invoked using JavaScript code that looks exactly like a regular JavaScript function call.

Most Windows Communication Foundation (WCF) services may be exposed as a service compatible with ASP.NET AJAX by adding an appropriate ASP.NET AJAX endpoint.

So what do we understand from the above texts? Let me try to explain this via a simple example. You have a mathematical website, you need to display a little Pascal series in few labels in your website and give some effects on that to make the website look cool. So what do you do now?

Have a AJAX enabled WCF service having an operation contract to do the coding part for your Pascal series, and call that service using Javascript code on to your labels, no need to perform any server-side coding here,save your website from performance glitches and lags.

Summary is you can directly communicate your WCF service from client side Javascript code.

Let's go ahead to some codes.

  1. Open your VS 2008 and click on New>WebSite.
  2. Image 14

  3. Select ASP.NET WebSite template and give the location as you would like.
  4. Image 15

  5. Right click on the AJAX project and click on 'Add New Item'. Select AJAX enabled WCF service from the list and give a name.
  6. Image 16

  7. Once you add the AJAX enabled WCF service, a class file will be opened which will have some default code. Here we have a [ServiceContract(Namespace="")] attribute. Specify the namespace as the project name you have given in this case AJAX. Write some operation contracts (methods) in the .cs file, which will be exposed ultimately. Have a look at the below code for further reference.
  8. C#
    using System;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.ServiceModel.Activation;
    using System.ServiceModel.Web;
    [ServiceContract(Namespace = "AJAX")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class MathService
    {
        // Add [WebGet] attribute to use HTTP GET
        [OperationContract]
        public int Multiplication(int a, int b)
        {
            return a * b;
        }
    }

    We have one operation contract which just multiplies 2 integers and returns back the result.Now let's configure the client to access the Service. 

  9. Open the Default.aspx page and drop a ScriptManager from the AJAX portion of the ToolBox. Then we need to configure the ScriptManager to accept the WCF service, something like below:
  10. XML
    <asp:ScriptManager ID="ScriptManager1" runat="server">
        <Services>
        <asp:ServiceReference Path="MathService.svc" />
        </Services>
    </asp:ScriptManager>

    You can also do this via Properties>Services (Add Collection). Now the script manager is configured, we need to do some designing in our page.

  11. Drop two  labels and two HTML type textboxes (basically Input (text)), 1 HTML type button on your Default.aspx page, something like below:
  12. XML
    <asp:Label ID="Label1" runat="server" Text="Enter one number:"></asp:Label>
    <input id="txtOne" type="text" />
    <br />
    <br />
    <asp:Label ID="Label2" runat="server" 
           Text="Enter another number:"></asp:Label>
    <input id="txtTwo" type="text" /><br />
    <br />
    <input id="btnClick" type="button" value="Click Me" onclick="return Multiply()" /><br />
    <div id="new"></div>

    We also have a div named as 'new' where we will display the result. The Default.aspx page will look something like below:

    Image 17

  13. Now comes the important part, to write the JavaScript code, be a little cautious over here. We have defined a function named as "Multiply()" in the onclick event of the button "Click Me", in this function itself we will configure as to how to call the WCF service's operation contract. Start coding as below in the Default.aspx page itself:
  14. JavaScript
    <script type="text/javascript" language="javascript"> 
        function Multiply() {
            var service = new AJAX.MathService();
            service.Multiplication($get("txtOne").value, 
                 $get("txtTwo").value, onSuccess, onFailure);
        }
        function onSuccess(result) {
            $get("new").innerHTML = "The multiplication is:"+result;
        }
        function onFailure(result) {
            window.alert(result.get_message());
        }
    </script>

    Now, let me explain the above JavaScript code. In the function Multiply(), we are creating a new variable named as "service" which is refering to the MathService service created earlier. Then we use the variable "service" to access the Operation Contract of the WCF service. We provide 4 parameters to the function, 2 are the values which a user's gonna type in the front-end, while rest 2 are further JavaScript functions which define, as to what will happen if the operation succeeds or not. Hence functions are called as onSuccess and onFailure. You can give whatever name you desire, but please remember to implement them.

    On the successful implementation of the operation contract, I have tried to encode a message on to the "new" div, while onFailure alerts the alert message, if the implementation fails. The code itself is almost self-explanatory.

  15. Build the solution, see for any errors, and then start debugging the project. It should happen something like below:
  16. Image 18 

Thus, we have seen how to create a AJAX enabled WCF service and how to call it from an ASP.NET client by using JavaScript.

Well, guess it is time to wrap up the article. In this article, we have learnt:

  • How to consume a WCF service via an ASP.NET WebSite.
  • How to code an AJAX enabled WCF Service and consume it in an ASP.NET Web Site

Points of Interest

I learnt a lot while writing this article.

I would like to share with the readers that we can't directly use a DataTable to bind data in a WCF service.It's actually bad practice.

If we are returning a DataTable from a WCF service, we are actually messing up with service-oriented architecture. The contract doesn't define what columns the DataTable contains. So if in future, the columns change, the client will be in problem, because the columns have changed but not the contract.

Provided that it isn't a good practice, we still can use a DataTable in a WCF service, by providing a TableName.

C#
DataTable dt=new DataTable();
dt.TableName="newTestTable";
//some codes over here
return dt;

I have attached the codes in the zipped folder. It has three projects basically, NewService, SampleWeb and AJAX.

NewService is the WCF service project, SampleWeb is the ASP.NET website project which is consuming the NewService. AJAX has the implementation of the AJAX enabled WCF service and its consumption via a web app. Make full use of the code and enjoy. 

History 

  • 2 April,2013: Version 1.0 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Systems Engineer
India India
An electronics engineer landed in the crazy .NET world...Smile | :) Smile | :)

Comments and Discussions

 
QuestionExcellent article, need a few clarifications Pin
Sunil Umesh8-Aug-13 8:35
Sunil Umesh8-Aug-13 8:35 
AnswerRe: Excellent article, need a few clarifications Pin
Anurag Sinha V8-Aug-13 20:00
Anurag Sinha V8-Aug-13 20:00 
GeneralRe: Excellent article, need a few clarifications Pin
Sunil Umesh8-Aug-13 20:39
Sunil Umesh8-Aug-13 20:39 
GeneralRe: Excellent article, need a few clarifications Pin
Anurag Sinha V10-Aug-13 8:49
Anurag Sinha V10-Aug-13 8:49 
AnswerRe: Excellent article, need a few clarifications Pin
Anurag Sinha V10-Aug-13 8:46
Anurag Sinha V10-Aug-13 8:46 
GeneralRe: Excellent article, need a few clarifications Pin
Sunil Umesh10-Aug-13 9:15
Sunil Umesh10-Aug-13 9:15 
GeneralRe: Excellent article, need a few clarifications Pin
Anurag Sinha V11-Aug-13 7:11
Anurag Sinha V11-Aug-13 7:11 
GeneralNice Article Pin
divyansh_ch29-Jul-13 1:57
divyansh_ch29-Jul-13 1:57 
GeneralRe: Nice Article Pin
Anurag Sinha V29-Jul-13 2:23
Anurag Sinha V29-Jul-13 2:23 
GeneralMy vote of 4 Pin
Sandesh M Patil3-Apr-13 9:54
Sandesh M Patil3-Apr-13 9:54 
GeneralRe: My vote of 4 Pin
Anurag Sinha V3-Apr-13 14:17
Anurag Sinha V3-Apr-13 14:17 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.