Pages

Thursday, May 23, 2013

Spring Frame Work .Net WCF Web Service

 I am using the Spring Frame Work .net to integrate the c# WCF Web Service. This web Service demonstrate the CRUD Operation capabilities and also spring dependency injection as follows.

1. Setting The Development Environment

 Installing the NuGet Extension

Please follow the NuGetInstall  link to install the nuget extension for visual studio 2010.

2 Creating the WCF Web Service Application

     Open the Visual Studio --> Click File --> New --> Project -->WCF and it will display the following screen.



Choose the WCF Service Application, and Enter the Name. In my example Name is MySampleWcfService and Click OK button. After Clicking the OK button and it will display the following directory structure.





3. Installing Spring and Dependency Libraries

Downloading the following Spring and dependency Libraries from the Nuget Repository.

Spring Packages

Spring.Core
Spring.Aop
Spring.Services

Spring Dependencies

Common.Logging
Common.Logging.Log4Net


Right Click on the References and Click Manage Nugget Packages and it will display the following screen.



Enter the Spring.Core in the search box and it will display the following screen.



Click Install Button and It will install the Spring.Core Package in the reference folder and it will display the following screen.



 Repeat the Same Steps for Spring.Aop, Spring.Services,Common.Logging and Common.Logging.Log4Net packages to install the references folder.


Reference Folder Structure

The packages are installed in the reference folder and package structure is shown below.




4.Developing Spring WCF Web Service

4.1 Rename The Service Files

Rename the meaning full names of the IService1.cs and Service.svc files.In My example I have rename from  IService1.cs to IAccountWcfService.cs and Service1.svc to AccountWcfService.svc file.

4.2 Develop the Data Contract

The service accept the data from the client. We are defining the data contract and it contains three fields. They are Id, Name, and AccountType. The sample data contact is shown below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.Serialization;
using System.ServiceModel;

namespace MySampleWcfService
{  
    [DataContract]
    public class Account
    {
        private string id;
        private string name;
        private string accountType;

        [DataMember]
        public string Id {
            set { this.id = value; }
            get { return id; }
        }
        [DataMember]
        public string Name
        {
            set { this.name = value; }
            get { return name; }
        }
        [DataMember]
        public string AccountType
        {
            set { this.accountType = value; }
            get { return accountType; }
        }

    }
}


4.2 Develop the Method Interceptor

The method interceptor is a AOP porgam and Intercept all the method request and logging the time. The Sample Program is given below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using AopAlliance.Intercept;
namespace MySampleWcfService
{
    public class SimplePerformanceInterceptor:IMethodInterceptor
    {
        private string prefix = "Invocation took";

        public string Prefix
        {
            get { return prefix; }
            set { prefix = value; }
        }

        public object Invoke(IMethodInvocation invocation)
        {
            string name = invocation.Method.Name;
            DateTime start = DateTime.Now;
            Console.WriteLine(name + "Start Time " + start);

            try
            {
              
                return invocation.Proceed();
            }
            finally
            {
                DateTime stop = DateTime.Now;
                Console.WriteLine(name + "End Time " + stop);
            }
        }

    }
}
4.3 Develop the Data Access Object

In my example I am going to store the Account object in memory using Dictionary Class. The Sample Class is Shown Below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MySampleWcfService.DAO
{
    public interface AccountMemDAO
    {
        void CreateAccount(Account account);
        void UpdateAccount(Account account);
        void DeleteAccount(string id);
        Account GetAccount(string id);

    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace MySampleWcfService.DAO
{
    public class AccountMemDAOImpl : AccountMemDAO
    {
        private IDictionary<string, Account> data = new Dictionary<string, Account>();

        public void CreateAccount(Account account)
        {
            data[account.Id] = account;
           
        }

        public void UpdateAccount(Account account)
        {
            data[account.Id] = account;
        }

        public void DeleteAccount(string id)
        {
            data.Remove(id);
        }

        public Account GetAccount(string id)
        {
            if (data.ContainsKey(id))
            {
                return data[id];
            }
            else
            {
                return null;
            }
        }
    }
}


4.4 Develop the Service Object

Add the Service Methods into the IMySampleWcfService.cs file and the sample code is given below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace MySampleWcfService
{
    [ServiceContract]
    public interface IAccountWcfService
    {
        [OperationContract]
        void CreateAccount(Account account);
        [OperationContract]
        void UpdateAccount(Account account);
        [OperationContract]
        void DeleteAccount(string id);
        [OperationContract]
        Account GetAccount(string id);
    }
}

4.5 Implement the Service Interface

The Sample Service Implementation is given below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using MySampleWcfService.DAO;
using MySampleWcfService.Exception;

namespace MySampleWcfService
{
    public class AccountWcfService : IAccountWcfService
    {
      
        private AccountMemDAO memdao;

        public void CreateAccount(Account account)
        {
            if(account==null)
            {
                throw new AccountWcfServiceException("The Account Object is Null");
            }
            if (account != null )
            {
                if(account.Id == null || account.Id.Trim().Equals(""))
                {
                    throw new AccountWcfServiceException("The Account Id Can Not be Null");
                }
            }
            Account acct = memdao.GetAccount(account.Id);
            if (acct == null)
            {
                memdao.CreateAccount(account);
            }
            else
            {
                throw new AccountWcfServiceException("The Account Id " + account.Id + " Already Exists.");
            }
        }

        public void UpdateAccount(Account account)
        {
            if (account == null)
            {
                throw new AccountWcfServiceException("The Account Object is Null");
            }
            if (account != null && (account.Id == null || (account.Id.Trim().Equals(""))))
            {
                throw new AccountWcfServiceException("The Account Id Can Not be Null");
            }
           
            Account acct = memdao.GetAccount(account.Id);
            if (acct != null)
            {
                memdao.UpdateAccount(account);
            }
            else
            {
                throw new AccountWcfServiceException("The Account Id " + account.Id + " Not Found.");
            }
        }

        public void DeleteAccount(string id)
        {
           
            if (id == null || id.Trim().Equals(""))
            {
                throw new AccountWcfServiceException("The Account Id Can Not be Null");
            }
           
            Account acct = memdao.GetAccount(id);
            if (acct != null)
            {
                memdao.DeleteAccount(id);
            }
            else
            {
                throw new AccountWcfServiceException("The Account Id " + id + " Already Exists.");
            }
        }

        public Account GetAccount(string id)
        {
            if (id == null || id.Trim().Equals(""))
            {
                throw new AccountWcfServiceException("The Account Id Can Not be Null");
            }

            Account acct = memdao.GetAccount(id);
            return acct;
        }

        public AccountMemDAO MemDao {

            set { this.memdao = value; }
        }
       
    }
}
 

4.5 Configuring the Web.Config File

4.5.1 Define the Spring Config Section

We need to define the section group and two sections. The section group name is spring and it is our root element for the spring configuration. The section name is context and holding the configuration resource info and another section name objects and it is being used to configure the spring beans.

<configSections>
    <sectionGroup name="spring">
      <section name="context" type="Spring.Context.Support.ContextHandler,Spring.Core"/>
      <section name="context" type="Spring.Context.Support.DefaultSectionHandler,Spring.Core"/>
    </sectionGroup>
  </configSections>




4.5.2 Define the Spring Context Section

<context>
      <resource uri="config://spring/objects"/>
</context>

In the above uri specifying the config location defined in the sequence of  <configSections><sectionGroup>Section>. Please refer section 4.5.1

4.5.3 Define the Spring Objects Section

The following objects needs to be configured. They are

<object id="memdao" type="MySampleWcfService.DAO.AccountMemDAOImpl, MySampleWcfService" singleton="true"/>

      <!-- Defining the Service -->
<!-- Defining the Service -->
      <object id="serviceopr" type="MySampleWcfService.AccountWcfService, MySampleWcfService" singleton="true">
        <property name="MemDao" ref="memdao"/>
      </object>
      

     
      <!-- Defining the Service Operation-->

      <object id="serviceOperation" type="Spring.Aop.Support.SdkRegularExpressionMethodPointcut,Spring.Aop">
        <property name="pattern" value="^MySpringWcfApp.*"/>
      </object>
     
      <!-- Defining the Method Interceptor -->

<object id="perfAdvice" type="MySampleWcfService.SimplePerformanceInterceptor, MySampleWcfService">
        <property name="Prefix" value="Performance"/>
      </object>
           
      <!-- Defining the AOP -->

      <aop:config>
        <aop:advisor pointcut-ref="serviceOperation" advice-ref="perfAdvice" />
      </aop:config>
 


4.5.4 Sample web.config file

<?xml version="1.0" encoding="utf-8"?>
<configuration>

  <configSections>
    <sectionGroup name="spring">
      <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core" />
      <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
    </sectionGroup>
  </configSections>

  <spring>
    <context>
      <resource uri="config://spring/objects"/>
    </context>
    <objects xmlns="http://www.springframework.net"
             xmlns:aop="http://www.springframework.net/aop">

    
      <object id="memdao" type="MySampleWcfService.DAO.AccountMemDAOImpl, MySampleWcfService" singleton="true"/>
    
      <!-- Defining the Service -->
      <object id="serviceopr" type="MySampleWcfService.AccountWcfService, MySampleWcfService" singleton="true">
        <property name="MemDao" ref="memdao"/>
      </object>
    
      <!-- Defining the Service Operation-->

      <object id="serviceOperation" type="Spring.Aop.Support.SdkRegularExpressionMethodPointcut,Spring.Aop">
        <property name="pattern" value="^MySampleWcfService.*"/>
      </object>
    
      <!-- Defining the Method Interceptor -->

      <object id="perfAdvice" type="MySampleWcfService.SimplePerformanceInterceptor, MySampleWcfService">
        <property name="Prefix" value="Performance"/>
      </object>
    
    
      <!-- Defining the AOP -->
    
      <aop:config>
        <aop:advisor pointcut-ref="serviceOperation" advice-ref="perfAdvice" />
      </aop:config>
    
    
    </objects>
  </spring>
 
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- 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 includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
  </system.webServer>
 
  <runtime>
 
       <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
 
            <dependentAssembly>
 
                 <assemblyIdentity name="Common.Logging" publicKeyToken="af08829b84f0328e" culture="neutral" />
 
                 <bindingRedirect oldVersion="0.0.0.0-2.1.2.0" newVersion="2.1.2.0" />
 
            </dependentAssembly>
 
       </assemblyBinding>
 
  </runtime>
</configuration>

The Sample Configuration is given below.

<%@ ServiceHost Language="C#" Debug="true" Service="serviceopr" Factory="Spring.ServiceModel.Activation.ServiceHostFactory" %>

6. Compile the Web Service
Click Build --> Build Solution. It will Compile the Source Files.
7. Deploy the Web Service.
Click the Build --> Click Publish MySampleWcfWebService and it will display the following screen.
 
Select or Import Publish Profile combo box --> New and It will display the following screen
 
After Entering the profile name and click Ok button and it will display the following screen.
 
 
Enter Service URL and Site/Application Name. In my example service name is host name(localhost) and site name is Default Web Site/MySampleWcfService. Click Next Button and it will display the following screen.




Click Next Button and It will display the following screen.


Click Publish Button and It will deploy the Web Service in the IIS Server.

After successfully deploy the web service and it will shown the following output in the console. 




8. Verifying the Deployed Web Service in IIS

Open the IIS Manager and verify our web service is deployed. The Web Service is Deployed Successfully and it will shown the following screen shot.




Right Click the MySampleWcFService and Click Switch to Content View and It will Display the following screen.



Right click on the AccountWcfService.svc file and Select Browse and it will display the following screen.



9. Testing the Web Service

Open the WcfTestClient.exe file and it is available in the location of "c:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\WcfTestClient.exe". After clicking the WcfTestClient.exe file and it will show the following screen.





Click File --> Add Service and It will display the following screen.




 
Enter the Service End oint Url and Click OK Button and It will fetch the service operation definitions as shown below.


Click CreateAccount and it will display the following screen.


Enter Id,Name,AccountType and Click Invoke Button. It will create the Account in Memory.  In My Example i have given id is 123, Name is TestName and AccountType is CreateAccount. We will verify using the GetAccount passing the id. Please click the GetAccount and it will display the following screen.




Enter Id is 123 and It will fetch the  stored account details and the detailed screen shot given below.



Please repeat the steps for Update Account and Delete Account.

References:


Best Of Luck