Issue While Returning DataTable Through WCF Service

Today, I have provided an article showing you how to return a datatable using a WCF service from C# code.

Issue While Returning DataTable Through WCF Service

Problem

In the previous article, I faced a common problem when returning a DataTable through a WCF Service. I'm receiving that error message when using one of my webmethods on my WCF webservice.

"The underlying connection was closed: The connection was closed unexpectedly."

This error only occurs when returning a DataTable. If I return some primitive type or even a Dictionary<string, string>, it returns no problem.

Iservice1.cs File

Now we create a function in the OperationContract section of the Iservice1.cs file:

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Runtime.Serialization;  
  5. using System.ServiceModel;  
  6. using System.ServiceModel.Web;  
  7. using System.Text;  
  8. using System.Data ;  
  9. namespace WCFServiceWith_ReturnTable  
  10. {  
  11.     [ServiceContract]  
  12.     public interface IService1  
  13.     {  
  14.         [OperationContract]  
  15.         DataTable SelectUserDetails();  
  16.     }  
  17.     // Use a data contract as illustrated in the sample below to add composite types to service operations.  
  18.     [DataContract]  
  19.     public class UserDetails  
  20.     {  
  21.        [DataMember]  
  22.         public DataTable UserRecord  
  23.         {  
  24.             get;  
  25.             set;  
  26.         }  
  27.     }  
  28. }  
Service.svc.cs File

In this file we define the function SelectUserDetails(UserDetails userInfo).

And replace the code with the following:

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Runtime.Serialization;  
  5. using System.ServiceModel;  
  6. using System.ServiceModel.Web;  
  7. using System.Text;  
  8. using System.Data.SqlClient;  
  9. using System.Data;  
  10. namespace WCFServiceWith_ReturnTable  
  11. {  
  12.     // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.  
  13.     public class Service1 : IService1  
  14.     {  
  15.         public DataTable  SelectUserDetails()  
  16.         {  
  17.             SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=registration;User ID=sa;Password=wintellect");  
  18.             con.Open();  
  19.             SqlCommand cmd = new SqlCommand("Select * from RegistrationTable", con);  
  20.             SqlDataAdapter sda = new SqlDataAdapter(cmd);  
  21.             DataTable  dt = new DataTable();  
  22.             sda.Fill(dt);  
  23.             cmd.ExecuteNonQuery();  
  24.             con.Close();  
  25.             return dt;  
  26.         }  
  27.     }  
  28. }   
Add a Service Reference to the WCF service in the Web Application using the Add Service Reference dialog box:

img2.jpg

Write following code in the web Application:

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5. using System.Web.UI;  
  6. using System.Web.UI.WebControls;  
  7. using ServiceReference1;  
  8. using System.IO;  
  9. using System.Data;  
  10. using System.Xml;  
  11. public partial class _Default : System.Web.UI.Page  
  12. {  
  13.     ServiceReference1.Service1Client objServiceClientobjService = new ServiceReference1.Service1Client();  
  14.     protected void Page_Load(object sender, EventArgs e)  
  15.     {  
  16.         DataTable dt = new DataTable();  
  17.         dt=objServiceClientobjService.SelectUserDetails();  
  18.         GridView1.DataSource = dt;  
  19.         GridView1.DataBind();  
  20.     }  
  21. }  
Now run the application. The following error will occur: 

img1.jpg

Returning DataTable in WCF

This is a serialization issue with WCF. Your Datacontract contains a type which the DataContractSerializer is not able to serialize. Here, we will introduce how to return a DataTable using a WCF service from C# code. To return a DataTable using a WCF service, we must do the following 3 things:

  1. Create Database Table
  2. Create WCF Service
  3. Create a Web Application

In the first step we will create a table in SQL Server; after that we create a simple function to return the table from the database using a WCF service. In a web application, add a reference of the service and data to be returned which will be sent to the web services function. Let's take a look at a practical example. The example application is developed in Visual Studio 2010 and SQL Server 2008.

Step 1: Creating Database Table

  1. Database name:  Registration
  2. Database table name: RegistrationTable

RegistrationTable Table

  1. CREATE TABLE [dbo].[RegistrationTable]  
  2. (  
  3.       [UserName] [varchar](100) NOT NULL,  
  4.       [Password] [varchar](20) NOT NULL,  
  5.       [Country] [varchar](100) NOT NULL,  
  6.       [Email] [varchar](200) NOT NULL  
  7. )  
Step 2: Creating WCF Service

Now you have to create a WCF Service:

  • Go to Visual Studio 2010
  • New -> Select a project

img3.jpg

Now click on the project and select WCF Service Application and provide a name for the service:

img4.jpg

Now click on the Ok Button. Then you will get 3 files in the Solution Explorer:

  1. IService.cs
  2. Service.svc
  3. Service.svc.cs

The following image shows the following files:

img5.jpg

For inserting data into the database you need to write the following code in the IService1.cs file which contains the two sections:

  1. OperationContract
  2. DataContract

The OperationContract section is used to add service operations and the DataContract is used to add types to service operations.

Iservice1.cs File

Now we create a function in the OperationContract section of the Iservice1.cs file:

  1. using System;    
  2. using System.Collections.Generic;    
  3. using System.Linq;    
  4. using System.Runtime.Serialization;    
  5. using System.ServiceModel;    
  6. using System.ServiceModel.Web;    
  7. using System.Text;    
  8. using System.Data ;    
  9. namespace WCFServiceWith_ReturnTable    
  10. {    
  11.     [ServiceContract]    
  12.     public interface IService1    
  13.     {    
  14.         [OperationContract]    
  15.         UserDetails SelectUserDetails();    
  16.     }    
  17.     [DataContract]    
  18.     public class UserDetails    
  19.     {    
  20.        [DataMember]    
  21.         public DataTable UserRecord    
  22.         {    
  23.             get;    
  24.             set;    
  25.         }          
  26.     }    
  27. }  
Service.svc.cs File

In this file we define the definition of the function SelectUserDetails(UserDetails userInfo).

And replace the code with the following:

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Runtime.Serialization;  
  5. using System.ServiceModel;  
  6. using System.ServiceModel.Web;  
  7. using System.Text;  
  8. using System.Data.SqlClient;  
  9. using System.Data;  
  10. namespace WCFServiceWith_ReturnTable  
  11. {  
  12.     // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.  
  13.     public class Service1 : IService1  
  14.     {  
  15.         public UserDetails SelectUserDetails()  
  16.         {  
  17.             UserDetails ObjUserDetail = new UserDetails();  
  18.             SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=registration;User ID=sa;Password=wintellect");  
  19.             con.Open();  
  20.             SqlCommand cmd = new SqlCommand("Select * from RegistrationTable", con);  
  21.             SqlDataAdapter sda = new SqlDataAdapter(cmd);  
  22.             DataTable dt = new DataTable("TableName");  
  23.             sda.Fill(dt);  
  24.             ObjUserDetail.UserRecord = dt;  
  25.             cmd.ExecuteNonQuery();  
  26.             con.Close();  
  27.             return ObjUserDetail;  
  28.         }  
  29.     }  
  30. }  
Step 3: Create web Application (Accessing the Service)

Now, you have to create a web site.

  • Go to Visual Studio 2010
  • New -> Select a website application
  • Click OK

img6.gif

Now add a new page to the website:

  • Go to the Solution Explorer
  • Right-click on the project name
  • Select add new item
  • Add new web page and give it a name
  • Click OK

img7.jpg

Add the service reference in web application

Now add the service reference.

img8.jpg

When we click on the add the service reference the following window will be opened:

img9.jpg

Now paste the above URL in the address and click on the go button.

img10.jpg

Click on the ok Button. Now the reference has been added in the Solution Explorer.

img15.jpg

Double-click the on the form and add the following code on the page load event:

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5. using System.Web.UI;  
  6. using System.Web.UI.WebControls;  
  7. using ServiceReference2;  
  8. using System.IO;  
  9. using System.Data;  
  10. public partial class _Default : System.Web.UI.Page  
  11. {  
  12.     ServiceReference2.Service1Client objServiceClientobjService = new ServiceReference2.Service1Client();  
  13.     ServiceReference2.UserDetails emp =  
  14.      new ServiceReference2.UserDetails();  
  15.     protected void Page_Load(object sender, EventArgs e)  
  16.     {  
  17.         DataTable dt = new DataTable();  
  18.         emp=objServiceClientobjService.SelectUserDetails();  
  19.         dt = emp.UserRecord;  
  20.     }  
  21. }  
Now use a breakpoint to show the database value in the table.

img12.jpg

Now press F5 to start debugging.

img13.jpg

Now click on the DataTable Visualizer to see the table.

img14.jpg

It works fine.