Sunday, October 13, 2013

WCF Restful Service example.

      This tutorial explains you about a Restful WCF service. Windows Communication Foundation (WCF) is a tool usually used to implement and deploy a service-oriented architecture (SOA).Clients can consume multiple services; services can be consumed by multiple clients. Services are loosely coupled to each other.
WCF implements many advanced Web services (WS) standards such as WS-Addressing, WS-ReliableMessaging and WS-Security. With the release of .NET Framework 4.0, WCF also provides RSS Syndication Services, WS-Discovery, routing and better support for REST services.

ENDPOINTS:

A WCF service communicates with the world through end point only. Endpoints remember like 'ABC'.
A- Address
B-Binding
C-Contract

Address (WHERE): It specifies about the service location. Clients will use the URL to communicate with the service.
Address format of WCF transport schema look like below
[transport]://[machine or domain][:optional port]

WCF supports transport schemas like HTTP, TCP, IPC, MSMQ and Peer Network.
Examples:
HTTP address format: http://localhost/5124/service
TCP address format: net.tcp://localhost/5124/service
IPC address format: net.pipe://localhost/5124/pipe
MSMQ address format: net.msmq://localhost/5124/service


Binding (HOW): It specifies about communication type i.e. how client  can connect with the service or using which protocols finds the services (SOAP, HTTP, TCP, MSMQ etc.).
WCF supports 9 types of Bindings:
1. BasicHttpBinding: Basic Web service communication. This is designed to expose a WCF service as a legacy ASMX web service, so that old clients can work with new services. When used by the client, this binding enables new WCF clients to work with old ASMX services. No security by default.
2. WsHttpBinding: It  uses HTTP or HTTPS for transport, and is designed to offer a variety of features such as reliability, transactions, and security over the Internet.
3. WsDualHttpBinding: It is similar to the Ws Binding except it also support the duplex contract.
4. WsFederationHttpBinding: It supports federated security and transaction.
5. MsmqIntegrationBinding: It communicates directly with MSMQ application. It supports transaction.
6. NetMsmqBinding: This uses MSMQ for transport and is designed to offer support for disconnected queued calls. It supports transaction.
7. NetNamedPipeBinding/IPC binding: This uses named pipes as a transport for same-machine communication. This binding won't accept the outside calls. It supports duplex contract and transactions.
 8. NetPeerTCPBinding: This uses peer networking as a transport. The peer network-enabled client and services all subscribe to the same grid and broadcast messages to it. It supports duplex contracts.
9. NetTcpBinding/Tcp Binding: Communication between WCF Service across computers. It supports duplex contracts, reliability and transaction.

Contract (WHAT): It specifies the interface between client and server. It identifies what is exposed by the service.
WCF defines 4 types of contracts

Service Contract: It describes which operations the client can perform on the service. There are 2 types of Service Contracts are:
1. ServiceContract: This attribute is used to define the interface.
2. OperationContract: This attribute is used to define the method inside the interface.

DataContracts: It defines the data types, that are passed from and to the service. WCF defines implicit contracts for built-in types such as int and string, but we can easily define explicit opt-in data contracts for custom types. There are 2 types of Data Contracts are
1. DataContract: This attribute is used to define the class.
2. DataMember: This attribute is used to define the properties.

Message Contract: It allows the service to interact directly with messages. Message contracts can be typed or untyped, and are useful in interoperability cases and when there is an existing message format we have to comply with.

Fault Contracts: It define which errors are raised by the service, and how the service handles and propagates errors to its clients. It is easy to find, what errors has occurred.

Here, I have given info about Endpoints because it is very important for any WCF application.

How to create Basic WCF Service Application using VS 10/12:

1. Click on New Project. Then select WCF Service Application under WCF.



2. You will get solution like below


By default, you will get 'Hello' method with BasicHttpBinding. Now, you have to do your own work here.
The actual code starts from here. First, design your model by creating new class. We are using Data Contracts concept here. Have a look at below code.

 [DataContract]
    public class UserModel
    {
        [DataMember]
        public int UserId { get; set; }
        [DataMember]
        public string FirstName { get; set; }
        [DataMember]
        public string LastName { get; set; }
        [DataMember]
        public string Email { get; set; }
        [DataMember]
        public string Password { get; set; }
        [DataMember]
        public int Phone { get; set; }

    }

Then create a interface for the service i.e. give the operations which is operated by clients. Here, we are using Service Contract concept. It supports POST, GET, DELETE and PUT modes.  Follow the below code.

[ServiceContract]
    public interface IPrakashSampleService
    {

        [OperationContract]
        [WebInvoke(Method = "POST", UriTemplate = "/SignUp",
        RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        bool SignUp(UserModel user);

        [OperationContract]
        [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle =                         WebMessageBodyStyle.WrappedRequest, UriTemplate = "GetUserDetails/{UserId}")]      
        UserModel GetUserDetails(string UserId);


        [OperationContract]
        [WebInvoke(Method = "DELETE", ResponseFormat = WebMessageFormat.Json, BodyStyle =                 WebMessageBodyStyle.WrappedRequest, UriTemplate = "DeleteUser/{UserId}")]      
        UserModel DeleteUser(string UserId);

        [OperationContract]
        [WebInvoke(Method = "PUT", UriTemplate = "/UpdateUser",
         RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        bool UpdateUser(UserModel user);

    }


Now, do some required changes in WEB.CONFIG file for REST.
Create a connection string to your DataBase.

<connectionStrings>
   
    <add name="SampleServices" connectionString="data source=TEJA-PC;Initial Catalog=DBNAME;User ID=USERNAME;Password=PASSWORD;" providerName="System.Data.SqlClient" />
 
  </connectionStrings>

  Then change the binding to webHttpBinding and declaring address, binding and contract. Follow the below code.

<system.serviceModel>
    <services>
      <service name="Prakash_RestWcfSample.PrakashSampleService" behaviorConfiguration="ServiceBehaviour">

        <endpoint address=""  binding="webHttpBinding" contract="Prakash_RestWcfSample.IPrakashSampleService" behaviorConfiguration="web">

        </endpoint>
      </service>
    </services>
    <bindings>
      <webHttpBinding>
        <binding name="webHttpBinding" crossDomainScriptAccessEnabled="true" />
      </webHttpBinding>
    </bindings>
    <behaviors>
      <endpointBehaviors>
        <behavior name="web">
          <webHttp automaticFormatSelectionEnabled="false" helpEnabled="true" />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
         <behavior name="ServiceBehaviour">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
         </behavior>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <serviceHostingEnvironment multipleSiteBindingsEnabled="true"  aspNetCompatibilityEnabled="true"/>
  </system.serviceModel>

Now, time to write service methods in PrakashSampleService.svc. I have used SQL Server STORED_PROCEDURES here. But, we can use LINQ queries also.

First, declare a connection string.
   
 string strcon = ConfigurationManager.ConnectionStrings["SampleServices"].ToString();
        SqlConnection con = null;
        SqlCommand cmd = null;
        SqlDataAdapter da = null;
        DataSet ds = null;

// POST METHOD

 public bool SignUp(UserModel userInfo)
        {

                using (con = new SqlConnection(strcon))
                {
                    cmd = new SqlCommand() { Connection = con, CommandText =                                     "Proc_SaveUserDetails", CommandType = CommandType.StoredProcedure };             

                    if (con.State == ConnectionState.Closed)
                    {
                        con.Open();
                        cmd.Parameters.AddWithValue("@UserID", userInfo.UserId);
                   
                        cmd.Parameters.AddWithValue("@FName", userInfo.FirstName);
                        cmd.Parameters.AddWithValue("@LName", userInfo.LastName);
                        cmd.Parameters.AddWithValue("@Email", userInfo.Email);
                        cmd.Parameters.AddWithValue("@Password", userInfo.Password);
                        cmd.Parameters.AddWithValue("@Phone", userInfo.Phone);

                        cmd.Parameters.Add("@Message", SqlDbType.VarChar, 50).Direction =                                                    ParameterDirection.Output;  
              
                        cmd.ExecuteNonQuery();
                       
                        string message = cmd.Parameters["@Message"].Value.ToString();
                        if (message == "Sucess")
                        {
                           
                            //do something here.

                        }
                        else
                        {
                            //do something here.
                        }
                    }
                    con.Close();

                }
                return true;
         
        }

//GET Method

 public UserModel GetUserDetails(string userid)
        {
            UserModel getuserdetails = new UserModel();
           
            using (con = new SqlConnection(strcon))
            {
                if (con.State == ConnectionState.Closed)
                {
                    con.Open();
                    cmd = new SqlCommand() { Connection = con, CommandText = "Proc_GetUserDetails",  CommandType = CommandType.StoredProcedure };                          
                    cmd.Parameters.AddWithValue("@UserID", userid);
                    SqlDataReader reader = cmd.ExecuteReader();
                    while (reader.Read())
                    {

                        getuserdetails.UserId = (int)reader["UserId"];
                        getuserdetails.FirstName = reader["FirstName"].ToString();
                        getuserdetails.LastName = reader["LastName"].ToString();
                        getuserdetails.Email = reader["Email"].ToString();
                        getuserdetails.Phone = (int)reader["Phone"];

                    }

                }
            }
            return getuserdetails;
        }



For help : your_service_url/help.You will find the all methods like below screen.
Ex: http://localhost:60273/PrakashSampleService.svc/help


The sample output in Json format:
Enjoy........!!
Read More »