In the last post, we saw how we can create a simple service and use the same. In this post, we will see how we can make use of session in WCF.
Introduction
Before using this functionality, we should make sure if we need to maintain session or not. By default, WCF does not support session.
For example, if we have a banking application, we need to always give the updated balance, we do not need to maintain the session at all. But if we have an E-Commerce application where a user can add anything in cart without logging into the system, we need to maintain the session.
Binding is also important if we are going to use the session, as only Ws-*, NetTCPBinding
and NetNamedPipeBinding
support this feature. If we try to configure with any other binding, the service will throw an exception saying this binding doesn’t support the session.
When using the session, we can control on which method call we need to start the session and on which method to end the session, as well as control the flow of method to be called.
By using IsInitiating
attribute, we can set on which method we need to start the session and IsTerminating
is used to set on which method to end the session.
Let’s create a new service using which we will see how a session can be used and useful.
- Let’s create our service first. To create service, Go to File-> New – > Project and from templates, select WCF and select WCF Service Library. Name the project as
MerchandiseService
and click ok.
- By default, we will have
IService1
and Service1.cs files. Let’s go ahead and rename IService1
as IMerchandiseService
and Service1
as MerchandiseService
. - We will have 4 methods,
Login
, AddToCart
, ReviewCart
and CheckOut
. Login
will initiate the session and CheckOut
will end the session. So let's go ahead and have these methods in our interface. - To control the use of session, we need to provide the property of
SessionMode
to true
with ServiceContract
Attribute. - Also make sure to change binding to
WsHttpBinding
, as basicHttpBinding
does not support Session
. We can find it in app. config file.
<endpoint address=”” binding=”wsHttpBinding” contract=”MerchandiseService.IMerchandiseService”>
- Our session will start with
Login
and end with CheckOut
method. If someone tries to call methods in the wrong sequence, we will get the exception. Let’s add methods to interface:
using System.ServiceModel;
namespace MerchandiseService
{
[ServiceContract(SessionMode = SessionMode.Required)]
public interface IMerchandiseService
{
[OperationContract(IsInitiating = true, IsTerminating = false)]
long Login(string loginName, string password);
[OperationContract(IsInitiating = false, IsTerminating = false)]
bool AddToCart(long loginId, long productId);
[OperationContract(IsInitiating = false, IsTerminating = false)]
bool ReviewCart(long cartId);
[OperationContract(IsInitiating = false, IsTerminating = true)]
bool CheckOut(long CartId);
}
}
- In this declaration,
IsInitiating = true
is set on Login
, it specifies that it will start the session
and CheckOut
has IsTerminating = true
which specifies this is the final method and should be called in the end. - Now let’s go ahead and implement the same in service. We will be using hard-coded values, but in real-life example, it will be
DataAccessLayer
.
namespace MerchandiseService
{
public class MerchandiseService : IMerchandiseService
{
public bool AddToCart(long loginId, long productId)
{
return true;
}
public bool CheckOut(long CartId)
{
return true;
}
public long Login(string loginName, string password)
{
return 10001;
}
public bool ReviewCart(long cartId)
{
return true;
}
}
}
- Done with the service, go ahead and press F5 to see if it is working or not, getting compiled, let’s add a client and use the same. We will use a console App to see how it works.
- Right click on project and Add – > New Project, select Windows and select Console Application and name this App as
MerchandiseClient
and click ok.
- Now let’s add service reference to our project, right click on references and select Add Service Reference, a dialog box will appear click on discover, as both are in same application, we can use this approach, in real-life, application service will be deployed on some server and we can enter the address and click on Go.
- Once service is discovered, you can click on service and get the methods under the service. Change the
Namespace
to MerchandiseService
and click on Advanced and from Collection Type, select System.Collections.Generic.List
and click ok.
- This reference will be added in web/app.config file available and we can change it once we are deploying our service on the other server. We can find
<endpoint>
in config file. - Now go ahead and use this service in our program.cs file.
using MerchandiseClient.MerchandiseService;
using System;
namespace MerchandiseClient
{
class Program
{
static void Main(string[] args)
{
try
{
using (MerchandiseServiceClient client = new MerchandiseServiceClient())
{
long loginId = client.Login("test", "test");
if (loginId > 0)
{
Console.WriteLine("User loggedin");
}
bool resultCart = client.AddToCart(loginId, 34445);
if (resultCart)
{
Console.WriteLine("Product Added to Cart");
}
bool resultReview = client.ReviewCart(345436);
if (resultReview)
{
Console.WriteLine("Cart review successful");
}
bool resultCheckOut = client.CheckOut(767867);
if (resultCheckOut)
{
Console.WriteLine("Order Placed");
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
}
}
- Now go ahead and press F5, we should get the below result.
- Now to check if
session
state is actually being managed, we will call CheckOut
before Review.
using MerchandiseClient.MerchandiseService;
using System;
namespace MerchandiseClient
{
class Program
{
static void Main(string[] args)
{
try
{
using (MerchandiseServiceClient client = new MerchandiseServiceClient())
{
long loginId = client.Login("test", "test");
if (loginId > 0)
{
Console.WriteLine("User loggedin");
}
bool resultCart = client.AddToCart(loginId, 34445);
if (resultCart)
{
Console.WriteLine("Product Added to Cart");
}
bool resultCheckOut = client.CheckOut(767867);
if (resultCheckOut)
{
Console.WriteLine("Order Placed");
}
bool resultReview = client.ReviewCart(345436);
if (resultReview)
{
Console.WriteLine("Cart review successful");
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
}
}
- Done with the changes, press F5, we will get the message shown when Review is called, saying
CheckOut
has already been called.
Conclusion
There are multiple questions which we need to ask if session
is actually needed or not. In most of the cases, it will not be required, but in case we need to maintain the state, we can go ahead and use this powerful feature of WCF.
In the next post, we will see use of instance within WCF.
You can also download the code from here.
You can follow my official Facebook page, and subscribe to my blog for more information.
You can also mail me on santosh.yadav19613@gmail.com in case you have any questions.