Expand and Load: Fetching related entities in WCF Data Service

Objective

In this post, I will show you how to retrieve data from related entities in WCF Data Service.

If you are new to this topic, please read Introduction to WCF Data service and ODATA before going through below article

Let us say, we want to fetch details from related entities Customers and Order.

clip_image001

There are two ways to fetch data from both related entities.

1. Expand

2. LoadProperty

Using LoadProperty

Program.cs

  NorthwindEntities context = new NorthwindEntities(new Uri("http://localhost:61091/WcfDataService1.svc/"));
                try
                {
                    foreach (Order o in context.Orders)
                    {
                        context.LoadProperty(o, "Customer");
                        Console.WriteLine("Customer : {0}- Order Id: {1}", o.Customer.ContactName, o.OrderID);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                Console.Read();
            }

In above code clip_image003 So in above code load property is being used to load data from related entities. Output clip_image005 Using Expand Program.cs

 DataServiceQuery<Order> query =
                context.Orders.Expand("Order_Details,Customer");
            try
            {
                foreach (Order order in query.Take(4))
                {
                    Console.WriteLine("Customer: {0}", order.Customer.ContactName);
                    Console.WriteLine("Order ID: {0}", order.OrderID);
                    foreach (Order_Detail item in order.Order_Details)
                    {
                        Console.WriteLine("\tProduct: {0} - Quantity: {1}",
                            item.ProductID, item.Quantity);
                    }
                }
            }
            catch (DataServiceQueryException ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.Read();

So in above code

clip_image007

In above code Orders relation is expanded to Order_detail and Customer.

clip_image009

In above code retrieving top 4th record and iterating through the records to display.

Output

clip_image011

WebException or Remote server name could not be resolved in WCF Data Service

Objective

This article will give a brief explanation on how to handle remote server name could not resolved exception in WCF Data Service

If you are new to this topic, please read Introduction to WCF Data service and ODATA before going through below article

Let us say, there is a WCF Data Service up and running on a particular server. We access that using below code at the client side

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Services.Client;
using ConsoleApplication1.ServiceReference1;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            DataServiceContext context = new DataServiceContext(
                                         new Uri("http://localhost:61091/WcfDataService1.svc/"));
            DataServiceQuery<Employee> query = context.CreateQuery<Employee>("Employees");
                foreach (Employee e in query)
                {
                    Console.WriteLine(e.FirstName);
                }
            Console.Read();
        }
    }
}

And output is as below,

clip_image002

Every this is fine till this point. Now let us go ahead and modify the WCF Data Service URL to a false URL

clip_image004

And URL, I am giving is false one. Server abc does not exist. Now after modification code will look like

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Services.Client;
using ConsoleApplication1.ServiceReference1;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            DataServiceContext context = new DataServiceContext(
                                         new Uri("http://abc:61091/WcfDataService1.svc/"));
            DataServiceQuery<Employee> query = context.CreateQuery<Employee>("Employees");
                foreach (Employee e in query)
                {
                    Console.WriteLine(e.FirstName);
                }
            Console.Read();
        }
    }
}

And when you try to run, you will get the run time exception as below,

clip_image005

Now to handle this exception put the foreach statement in try catch , so no modified code will look like

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Services.Client;
using ConsoleApplication1.ServiceReference1;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            DataServiceContext context = new DataServiceContext(
                                         new Uri("http://abc:61091/WcfDataService1.svc/"));
            DataServiceQuery<Employee> query = context.CreateQuery<Employee>("Employees");
            try
            {
                foreach (Employee e in query)
                {
                    Console.WriteLine(e.FirstName);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.Read();
        }
    }
}

And now running output will be as below,

clip_image007

Step by Step walk Through on URL routing in ASP.Net 4.0

Objective

URL Routing is new feature in ASP.Net 4.0. This article will give a walkthrough on how to work with URL Routing and an introduction of that.

URL Routing

ASP.Net 4.0 URL Routing enables mapping between search engines optimized URL to physical web Form pages.

For example

http://localhost:36774/Products/All URL will be mapped to http://localhost:36774/AllProduct.aspx

Here the first URL is more search engine optimized. Using the routing engine ASP.Net 4.0 perform URL mapping.

Follow the below steps to see how to work with URL routing

Step 1

a. Open Visual studio

b. Create new project

c. Select ASP.Net Web Application from Web tab

d. Give any name of the project. I am giving RoutingDemo for purpose of this article.

clip_image002

Step 2

a. Right click on the project

b. Add a new folder

clip_image003

c. Give any name of your choice to the folder. I am giving name Model for purpose of this article

clip_image004

So after creating a new folder, you can see Model folder in solution explorer.

Step 3

a. Right click on Model folder and select Add new item

clip_image005

b. From Data tab select Linq to SQL classes . Give any name of your choice. I am giving name here NorthWindProduct for purpose of this article

clip_image007

c. Click on Server Explorer

clip_image008

d. From the Server Explorer , right click on Data Connections and select add connection

clip_image009

e. Below pop window will come.

clip_image010

Give data base server name at first. Select the authentication mode, you use to connect to your database and then select NorthWind data base. After giving these three fields click OK.

f. From Server explorer, expand the NorthWind database connection. From table tab select Product and drag it in design surface

clip_image011

g. After dragging on the design surface NorthWindProduct.dbml file as below

clip_image012

h. In solution explorer you can see inside Model folder three files. There is a NorthWindProductDataContext class inside RoutingDemo.Model name space , we will be using as data context

clip_image013

Step 4

We want to navigate to two different pages.

1. Select all Products (AllProduct.aspx) : This page will display all the Products

2. Select a particular product on basis of Product name. (ParticularProduct.aspx): This page will display product detail of given product name.

Step 4a

a. Right click on site.master in solution explorer. And add a content page

clip_image014

b. Now in solution explorer , you can notice you have WebForm.aspx

clip_image015

c. Right click on WebForm.aspx and rename this to AllProduct.aspx

clip_image016

After renaming the name, you will have AllProduct.aspx in solution explorer.

clip_image017

Step 4B

Follow the steps exactly the same as step 4A and add one more web form. Give name of this form as ParticularProduct.aspx instead of AllProduct.aspx. So now in solution explorer you can see two web forms has been added.

clip_image018

Step 4C

a. Open AllProduct.aspx

b. Drag GridView from Data tab of tool box and put it on AllProduct.aspx

clip_image019

So, in design AllPrduct.aspx will look as below,

clip_image021

AllProduct.aspx will look like below,

    <%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" 
        CodeBehind="AllProduct.aspx.cs" Inherits="RoutingDemo.WebForm1" %>

    <asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">

    </asp:Content>

   <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

   <asp:GridView ID="GridView1" runat="server"> 
   </asp:GridView>

  </asp:Content>

Now we need to write code to fetch data from LINQ to SQL class

AllProduct.aspx.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using RoutingDemo.Model;
    namespace RoutingDemo
    {
        public partial class WebForm1 : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                GridView1.DataSource = Products;
                GridView1.DataBind();
            }
            private List<Product> _Product= null ;
            protected List<Product> Products
            {
                get
                {
                    if (_Product == null)
                    {
                        NorthWindProduct_DataContext context = new NorthWindProduct_DataContext();
                        return context.Products.ToList();
                    }
                    return _Product;
                }
            }
        }
    }

Explanation of Code

1. Put the namespace

clip_image022

2. Crated a protected property. In getter, I am checking for data member. If it is null, then I am creating instance of NorthWindProduct and fetching all the products.

clip_image024

3. On page load putting the property as data source of grid view.

clip_image025

Step 4D

a. Open ParticularProduct.aspx

b. Drag GridView from Data tab of tool box and put it on ParticularProduct.aspx

clip_image019[1]

So, in design ParticularProduct.aspx will look as below,

clip_image026

ParticularProduct.aspx will look like below,

   <%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true"  
CodeBehind="ParticularProduct.aspx.cs" Inherits="RoutingDemo.WebForm2" %>

   <asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">

    </asp:Content>

    <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <asp:GridView ID="GridView1" runat="server">

   </asp:GridView>

   </asp:Content>

Now we need to write code to fetch data from LINQ to SQL class

ParticularProduct.aspx.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using RoutingDemo.Model;
namespace RoutingDemo
{
    public partial class WebForm2 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            GridView1.DataSource = new Model.Product[] { Products };
            GridView1.DataBind();
        }
        private Product _Product = null;
        protected Product Products
        {
            get
            {
                if (_Product == null)
                {
                    string prdName = Page.RouteData.Values["Name"] as string;
                    NorthWindProduct_DataContext context = new NorthWindProduct_DataContext();
                    return context.Products.Where(prd => prd.ProductName.Equals(prdName)).SingleOrDefault();
                }
                return _Product;
            }
        }
    }
}

Explanation of Code

1. Put the namespace

clip_image022[1]

2. Crated a protected property. In getter, I am checking for data member. If it is null, then I am creating instance of NorthWindProduct and fetching product with the given name

clip_image028

Here Name is the parameter name in the Route URL.

Step 5

Now open Global.asax

clip_image030

When you click on Global.ascx.cs . You will get below default code

clip_image031

Now we need to add

1. Name space

clip_image032

2. Method

clip_image034

In first mapPageRoute

All Product -> name of the rule in Global.ascx

Products/All -> Routing URL

~/AllProduct.aspx -> Name of the physical aspx file.

In second mapPageRoute

Selected Product -> name of the rule in Global.ascx

Products/Selected/ {name} -> Routing URL where name is the parameter

~/ParticularProduct.aspx -> name of the physical file

3. Call the above created method in application start

clip_image035

Global.ascx.cs

Step 6

Step 6a

Now open default.aspx

1. Drag two buttons from tool box and put on the page

2. Drag a text box and put on the page

3. Attach button click handler for both the button

Default.aspx

    <%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"

    CodeBehind="Default.aspx.cs" Inherits="RoutingDemo._Default" %>

   <asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
    </asp:Content>

   

   <asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">

  

   <h2>

  

  Welcome to ASP.NET 4.0 Routing Feature

  

  </h2>

  

  <asp:Button ID="btnAllProducts" runat="server" Text="All Products"

  

  Width="129px" onclick="btnAllProducts_Click" /><br />

  

   <asp:Button ID="btnSelectedProduct" runat="server" Text="Select Product"

  

   onclick="btnSelectedProduct_Click" />

  

   <asp:TextBox ID="txtSearch" runat="server" Width="167px"></asp:TextBox>

  

   </asp:Content>

  

Step 6b

On click event of btnAllProducts

clip_image037

There is no input parameter.

On click event of btnSelectedProduct

clip_image039

Here input parameter to navigate is in txtSearch text box.

Default.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace RoutingDemo
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
           // txtSearch.Text = "";
        }
        protected void btnAllProducts_Click(object sender, EventArgs e)
        {
            Response.RedirectToRoute("All Product");
        }
        protected void btnSelectedProduct_Click(object sender, EventArgs e)
        {
            Response.RedirectToRoute("Selected Product", new { name = txtSearch.Text });
        }
    }
}


Run the application

clip_image041

If you notice the above output and URL in address bar, it is

http://localhost:36774/Default.aspx

Now on clicking of All Products

clip_image043

Now if you see the URL in address bar

http://localhost:36774/Products/All

And this URL is search engine optimized URL.

In the same way when you click on Select Product button it will navigate to

http://localhost:36774/Products/Selected/Chai

Chai is the product name.

Conclusion

In this article, we saw what Routing mapping feature of ASP.Net 4.0. I hope this article was useful. Thanks for reading. Happy coding.

Select and SelectMany: LINQ projection operator

Projection transforms the query result into the form defined by the developer. There are two projection operators in LINQ

image

Let us say, there is a class

clip_image004

And a function returning List<Student> as below,

clip_image006

Select operator

Below query will return name and roll number of all the students.

clip_image008

Output

clip_image010

Below query will project name of the student’s starts with D.

clip_image012

Output

clip_image014

Above was very simple query let us modify the display function and try to display subject of the student

clip_image015

Output

clip_image017

If you notice the above output, we are not getting the proper output and it is saying that Subject is generic list. So to fetch we need to enumerate through the list.

Now question is how to retrieve all the subjects of students?

SelectMany

So to retrieve query from more than one collection SelectMany come into action.

clip_image019

Above query will return the entire subjects of all the students.

clip_image021

The other way to apply SelectMany operator is directly apply on the retrieval query as below,

clip_image023

Output

clip_image025

Full Source code is as below,

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace ConsoleApplication9

{

class Program

{

static void Main(string[] args)

{

// Reteriving all students with name D

var result1 = from r in GetStudents()

where r.Name.StartsWith("D")

select r;

foreach (var r in result1)

{

Console.WriteLine(r.Name);

}

// Reteriving  the result in Anonymous  class

var result2 = from r in GetStudents()

select new { r.RollNumber, r.Name };

foreach (var r in result2)

{

Console.WriteLine(r);

}

// Reteriving using SelectMany

var result3 = from r in GetStudents()

select r;

foreach (var r in

result3.SelectMany(Student => Student.Subject))

{

Console.WriteLine(r);

}

// directly applying  SelectMany

var result = GetStudents().AsQueryable().SelectMany(Subject => Subject.Subject);

foreach (var r in result)

{

Console.WriteLine(r);

}

Console.Read();

}

static List<Student> GetStudents()

{

List<Student> students = new List<Student>{

new Student {

Name = "Dhananjay",

RollNumber ="1" ,

Subject= new List<string>{"Math","Phy"}},

new Student {

Name = "Scott",

RollNumber ="2" ,

Subject= new List<string>{"Che","Phy"}},

new Student {

Name = "John",

RollNumber ="3" ,

Subject= new List<string>{"Hindi","Phy"}}};

return students;

}

}

class Student

{

public string Name { get; set; }

public string RollNumber { get; set; }

public List<string> Subject { get; set; }

}

}


I hope this article was useful. Thanks for reading. Happy Coding

Learning Video on LINQ to SQL Class

Source Code


using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace ConsoleApplication9

{

class Program

{

static void Main(string[] args)

{

StudentDemoDataContext context = new StudentDemoDataContext();

#region Reterive

//Reteriving all the Records

foreach (var r in context.Students)

{

Console.WriteLine(r.Name + r.Subject);

}

#endregion

#region Insert

Student std = new Student

{

RollNumber = "8",

Name = "Mahesh",

Subject = "C#"

};

context.Students.InsertOnSubmit(std);

context.SubmitChanges();

#endregion

#region Update

Student std = (from r in context.Students

where r.RollNumber == "1"

select r).First();

std.Name = "Scott";

std.Subject = "ASP.Net MVC";

context.SubmitChanges();

#endregion

#region Delete

StudentDemoDataContext context1 = new StudentDemoDataContext();

Student std = new Student

{

RollNumber = "8",

Name = "Mahesh",

Subject = "C#"

};

context.Students.Attach(std);

context.Students.DeleteOnSubmit(std);

context.SubmitChanges();

#endregion

Console.Read();

}

}

}

Basic of C#: Call Stack, Call Site and Stack unwinding

Objective

In this article, I will explain three basic terms of C#

1. Call Stack

2. Call Site

3. Stack Unwinding

Let us say, you got the below code

Program.cs


using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace ConsoleApplication7

{

class Program

{

static void Main(string[] args)

{

Method1();

Console.Read();

}

static void Method1()

{

Method2();

Console.WriteLine("Method1");

}

static void Method2()

{

Method3();

Console.WriteLine("Method2");

}

static void Method3()

{

Method4();

Console.WriteLine("Method3");

}

static void Method4()

{

Method5();

Console.WriteLine("Method4");

}

static void Method5()

{

Console.WriteLine("Method5");

}

}

}

I have just created five dummy methods and calling them in nested manner. The methods, I have created are Method1 to Method5. If you run the above program , you will get output as below

clip_image002

If you examine the output, Methods are being called in reverse order.

Program is putting the methods in stack as below,

clip_image003

What is Call Stack?

Here, we are calling a method inside a method and so on and this is called CALL STACK.

clip_image004

Call Stack is the process of calling method inside a method.

Mathematically, we can say

clip_image006

What is Stack Unwinding?

Once the method call is completed that method is removed from the stack and this process is known as Stack Unwinding.

clip_image008

What is Call Site?

In above program, we are calling Method3 from Method2, so we can say Method2 is call site of Method3

clip_image010

Basics of C#: Checked and Unchecked Conversions

Objective

In this article, I will discuss about Checked and unchecked keyword and conversions in C#.

Consider the below code

Program.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace ConsoleApplication7

{

class Program

{

static void Main(string[] args)

{

int number = int.MaxValue;

number = number + 1;

Console.WriteLine(number);

Console.Read();

}

}

}

Now, if you see the above code

1. We are taking maximum integer value in a variable. And that is 2147483647.

clip_image001

2. We are increasing the number by 1. Now here it should get overflow because an integer variable cannot hold a number greater than 2147483647

clip_image002

So, now data will overflow and truncate during the assignment.

So, as the output we will get

clip_image004

If you notice above output, number assigned is truncated to –2147483647

It happened because compiler is doing unchecked compilation

So forcefully do the checked compilation, we will use CHECKED keyword. Just put all the codes in between checked block

clip_image006

So, now to avoid truncating during overflow assignment, we need to put our code in between Checked block.

So, modify the above code as below

Programs.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace ConsoleApplication7

{

class Program

{

static void Main(string[] args)

{

checked

{

int number = int.MaxValue;

number = number + 1;

Console.WriteLine(number);

Console.Read();

}

}

}

}

Now if you run the above code, you will get the below error.

clip_image007

It shows if the code is in checked block then rather than truncating at overflow, compiler is throwing an exception.

If we are doing checked compilation then to override that, we can put our code in Unchecked Block

clip_image009

You can change the behavior of compiler from checked to unchecked through command prompt.

WebServiceHost : Hosting a WCF REST Service

Objective

In this article, I will explain

1. What is WebServiceHost Factory class?

2. What is its function?

3. Where to use it?

4. One sample on hosting WCF REST Service using WebServiceHost.

What is WebServiceHost factory?

1. This is useful to host WCF REST End points.

2. This is derived from ServiceHost.

3. WebServiceHost has some extra functionality.

4. WebServiceHost works exactly the same way ServiceHost works.

WebServiceHost factory perform following special task

image

Where to use it?

image

How to choose between ServiceHost and WebServiceHost?

image

Example

In this example, I will show you step by step, how we can create a REST Service and host it in a console application using WebServiceHost factory.

To see the complete step by step walkthrough , follow my below article.

Hosting WCF REST Service in Console Application.

I hope this post was useful. Thanks for reading. Happy coding.

LINQ with IIS sites and web Applications

Objective

In this article, we will see how to work with LINQ against IIS.

Before applying LINQ against IIS sites and application pool, we need to set up the environment. Follow the bellows steps to do this.

Step 1

Down load Microsoft.Web.Administration.dll and save to a particular directory. I am saving it in D drive of local storage.

Step 2

Create a new console project and add Microsoft.Web.Administration dll as service reference. To add a reference right click on the project and click add service reference. Then browse to the directory where, we have saved the downloaded dll of the first step.

clip_image001

Step 3

Add the name space

clip_image002

Now we are ready to perform the query,

Display all the sites

clip_image004

Output

clip_image006

Display all the sites which is started

clip_image008

Output

clip_image009

Display Site running in a particular application pool

clip_image011

In above query, we are performing nested query. We are just comparing if application pool name is as same as given name or not.

Output

clip_image006[1]

Conclusion

In above article, I just discussed three basic LINQ query against IIS. I hope this post was useful . Thanks for reading. Happy Coding.

CollectionDataContract Attribute in WCF

This article is part # 2 of custom collection in WCF

Objective

In this article, I will explain you what is CollectionDataContract Attribute in WCF and why need it?

I strongly recommend you to read custom collection in WCF first.

Why we need it?

If you notice when we expose a custom collection, it must have

1. Add method

2. Implement IEnumerable and IEnumerable<T>

3. Custom collection is serlializable

Now let us go ahead and remove these two things which we added before in our custom collection

Previously the custom collection was

clip_image002

Now even if you remove the entire three prerequisite to work with custom collection and modify this custom collection as

clip_image003

And work with above custom collection you will not get any compile or run time error. So as the result, you would end up with corrupted data at the client side.

One more problem in above approach is that we have to put serlializable attribute explicitly.

And at the client side we are working with array and at the service side it is custom collection.

So, to solve above three problems we do have CollectionDataContract attribute.

clip_image004

So, now go ahead and modify the custom collection as below,

1. Open the MyCustomCollection class .

2. Add the name space System.Runtime.Serialization

clip_image006

3. Put the attribute CollectionDataContract

clip_image008

Here if you notice, I am providing the name value in the constructor of CollectionDataContract . This name (MyCollection) will be exposed as the name of generic link list at the client side.

So entire MyCollection class will look like,

MyCollection.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Collections;

using System.Runtime.Serialization;

 

namespace CRUDOperation

{

    [CollectionDataContract(Name="MyCollectionof{0}")]

    public class MyCustomCollection<T> : IEnumerable<T>

 

   {

        private List<T> myList = new List<T>();

 

 

 

        public void Add(T c)

        {

            myList.Add(c);

        }

 

        IEnumerator<T> IEnumerable<T>.GetEnumerator()

        {

            return myList.GetEnumerator();

        }

 

        System.Collections.IEnumerator IEnumerable.GetEnumerator()

        {

            return myList.GetEnumerator();

        }

 

 

    }

}

Now I will use this custom class in service and expose it to the client as

IService1.cs

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Runtime.Serialization;

    using System.ServiceModel;

    using System.ServiceModel.Web;

    using System.Text;

    using System.Runtime.Serialization;

 

    namespace CRUDOperation

    {

 

    [ServiceContract]

     public interface IService1

        {

            [OperationContract]

             MyCustomCollection<Student> GetStudents();

            [OperationContract]

            void Add(Student s);

         }

 

    public class Student

    {

    public string RollNumber { get; set; }

    public string Name { get; set; }

 

    }

 

    }

 

Service1.svc.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Runtime.Serialization;

using System.ServiceModel;

using System.ServiceModel.Web;

using System.Text;

 

namespace CRUDOperation

{

 

    public class Service1 : IService1

    {

        MyCustomCollection<Student> lstStudent = new MyCustomCollection<Student>();

 

        public MyCustomCollection<Student> GetStudents()

        {

 

            return lstStudent;

        }

        public void Add(Student s)

        {

            lstStudent.Add(s);

        }

 

    }

}

 

Now when you expose this service at the client side, in the Meta data of service the custom collection will be exposed as generic link list.

Let us say you have added the service in the client by choosing add service reference. Now click on the object explorer and Service1Client class, you can see that GetStudents class return type is MyCollectionOfStudent.

clip_image010

If you remember, I have given the name attribute of the CollectionDataContract attribute as MyCollectionOf{0} . So it has taken Student as the parameter and return type is exposed as MyCollectionOfStudent.

If you closely notice the object explorer you will find there is a class called MyCollectionOfStudent has been created.

clip_image011

So at the client side we can access the custom collection as below,

clip_image013

So complete client code can be as below,

Program.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using ConsoleApplication1.ServiceReference1;

 

namespace ConsoleApplication1

{

    class Program

    {

        static void Main(string[] args)

        {

            Service1Client proxy = new Service1Client();

            proxy.Add(new Student { RollNumber = "1", Name = "DJ" });

            MyCollectionofStudent students = proxy.GetStudents();

            foreach (var r in students)

            {

                Console.WriteLine(r.Name);

            }

            Console.Read();

        }

    }

}

 

Conclusion

I hope this article was useful to you. Thanks for reading. Happy coding.