C#

Simple Self Hosted WCF Service in C#

Self Hosting : 

In this post we will explain about self host service using console application in windows application. This referred as self hosting WCF service, the exact meaning of Self Hosted is provides the user to host the service in any application that could be Console Application or Windows forms etc. Earlier we saw about What is WCF service on dot net platform. We can host WCF service in IIS and windows service also.
Service can also be in-pro i.e. client and service in the same process. Now let's us create the WCF service which is hosted in Console application. We will also look in to creating proxy using 'Client Base' class.

Step 1 :  First let's start create the Service contract and it implementation. Create a console application and name it as WCF_NewsService. This is simple service which return News.
Step 2 : Add the System.ServiceModel and System.runtime.serialization reference to the project.
Step 3 : Now right click the project name  in solution explorer and got to the add new item and select WCF Service option in window  and give name News_Service and click  Add
Once you add this WCF Service some function and class files added into the solution explorer
Step 4 : an INews_Service interface, Add ServiceContract and OperationContract attribute to the class and function as shown below. You will know more information about these contracts in later session. These contracts will expose method to outside world for using this service.

INews_Service.cs
using System;


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

namespace WCF_NewsService
{
    
    [ServiceContract]
    public interface INews_Service
    {
        [OperationContract]
        TOInews Getnews(int a);

    }

    [DataContract]
    public class TOInews
    {
        private int _id;
        private string _header;
        private string _body;

        [DataMember]
        public int ID
        {
            get { return _id; }
            set { _id = value; }
        }

        [DataMember]
        public string Header
        {
            get { return _header; }
            set { _header = value; }
        }

        [DataMember]
        public string Body
        {
            get { return _body; }
            set { _body = value; }
        }
    }
}
Step 5 :  Open New_Service file and right click on INews_Service go to the implement Interface and delete the DoWork() method which unused for us. And write code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WCF_NewsService
{
   
    public class News_Service : INews_Service
    {


        #region INews_Service Members

        public TOInews Getnews(int a)
        {
            TOInews objtoinews = new TOInews();

            switch (a)
            {
                case 1:
                    {
                        objtoinews.ID = 1;
                        objtoinews.Header = "Mumbai News";
                        objtoinews.Body = "2013 Code contest quiz orgnize by TOI";
                        break;
                    }
                case 2:
                    {
                        objtoinews.ID = 2;
                        objtoinews.Header = "Pune News";
                        objtoinews.Body = "commonwealth fraud in pune ";
                        break;
                    }
                case 3:
                    {
                        objtoinews.ID = 3;
                        objtoinews.Header = "Solapur News";
                        objtoinews.Body = "New IT hub in Solapur";
                        break;
                    }
           
                default:
                    {
                        break;
                    }
            }

            return objtoinews;
           
        }

        #endregion
    }
}
Step 6 :  Now after completing write code in service we have to Start our service using console application  Below code show the implementation of the host process.

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

namespace WCF_NewsService
{
    class Program
    {
        static void Main(string[] args)
        {
            ServiceHost host = new ServiceHost(typeof(News_Service));
            host.Open();
            Console.WriteLine("Host Open Sucessfully ...");
            Console.ReadLine();
        }
    }
}
 Step 7 : 
now open app.config file and change some setting
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
     
     
     
      <bindings>
        <basicHttpBinding>
          <binding name="Pramod"></binding>
        </basicHttpBinding>
      </bindings>
     
     
       
     
      <behaviors>
            <serviceBehaviors>
                <behavior name="">
                    <serviceMetadata httpGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="false" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
     
     
     
        <services>
            <service name="WCF_NewsService.News_Service">
                <endpoint address="News_Service"
                          binding="basicHttpBinding"
                          contract="WCF_NewsService.INews_Service"
                          bindingConfiguration="Pramod">
                    <identity>
                        <dns value="localhost" />
                    </identity>
                </endpoint>
                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:8732/Design_Time_Addresses/WCF_NewsService/News_Service/" />
                    </baseAddresses>
                </host>
            </service>
        </services>
     
     
     
     
    </system.serviceModel>
</configuration>
Step 8 : Run your application and see message in console screen.


Now create consumer for consume the service. Again you have to create new application and write code in Program.cs file, 
Before writing code these file we need add service reference of NewsService Project
For adding the service reference right click to WCF_NewsConsumer in solution explorer and go to the Add Service reference.. copy the URL from Service project and paste it in Address location and give appropriate name to the Service.
Here I am giving name as Proxy_TOInews for namespace pupose and click OK
After adding the reference add namespace 
using WCF_NewsConsumer.Proxy_TOInews;



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

namespace WCF_NewsConsumer
{
    class Program
    {
        static void Main(string[] args)
        {
            Proxy_TOInews.News_ServiceClient proxy = new News_ServiceClient("BasicHttpBinding_INews_Service");
            TOInews Tnews = new TOInews();

            Console.WriteLine("Enetr News Id :");
            string newsid = Console.ReadLine();

            Tnews = proxy.Getnews(Convert.ToInt32(newsid));

            News nws = new News();
           
            nws.cID = Tnews.ID;
            nws.cHeader = Tnews.Header;
            nws.cBody = Tnews.Body;

            Console.WriteLine(" News from:" + nws.cID + "\r\r \n " + nws.cHeader + "\r\r \n " + nws.cBody + "");
            Console.ReadLine();

        }

        public class News
        {
            private int _id;
            private string _header;
            private string _body;

            public int cID
            {
                get { return _id; }
                set { _id = value; }
            }

            public string cHeader
            {
                get { return _header; }
                set { _header = value; }
            }

            public string cBody
            {
                get { return _body; }
                set { _body = value; }
            }
           
        }
    }
}

Now run the Both application and enter new id and hit enter key .


Simple WCF Service

Whats is the WCF

Download Newsarticle
Build Service Oriented Applications
The application in this scenario is connected. The leading approach to building connected applications is service orientation. No doubt, you have heard of Service Oriented Architecture (SOA), but what is a service-oriented application?
A service is a program that performs a task and that a client application can communicate with through well-defined messages. To call a Web or WCF service, the client passes it a message, which consists of XML. The message will typically include a request for the service to perform an action, such as retrieve or update the inventory information for a product. If the service returns data to the client, it passes back a message, also consisting of XML.
The client and the service need to agree on what the XML will look like. The most common message format is Simple Object Access Protocol (SOAP). SOAP defines the format of XML request and reply messages and how clients and services encode the data in the messages.
In object-oriented programming, objects are tightly coupled. To call the Inventory component, a client application creates an instance of the component and therefore, controls its lifetime. In a service-oriented application, services and clients are loosely coupled. To call the Inventory service, a client does not instantiate an instance of a component. It simply passes a message to the service and may receive a message in return.

Service-oriented applications are loosely coupled. All communication occurs through messages. SOAP defines the format of messages. Contracts define the contents of messages. A service will publish a contract that specifies what methods clients can call, what arguments those methods take and what, if anything, the methods return. The contract can also specify security requirements and whether a transaction is required.

ABC of WCF

Address: WCF services must have an address. The address specifies the location of the service which will be exposed for clients that will use it to communicate with the service. The address's protocol that WCF can provided: HTTP , TCP ,NamedPipe , Peer2Peer ,MSMQ.
Binding: Specifies how a service is accessible. In other words: how the two parties will communicate in terms of transport (HTTP , TCP ,NamedPipe , Peer2Peer ,MSMQ) ,encoding (text, binary etc.).
Contract: List of methods which can be executed by a remote client.

Endpoints
A Service created with WCF is hosted by the .NET framework. To expose services, we use configuration files and define Service-Endpoints. Service-Endpoints serve as a directive to the .NET framework instructing it about how a service should be exposed
Service Endpoints contain 3 parts Address,Binding,Contract.
Address formats can be relative or absolute. There are ways to define default or base addresses in the configuration file. Address will contain the protocol keyword in the beginning depending on the type of Binding being used. For example, bindings using Http protocol, your address will start with ‘http://’ and for binding using tcp protocol, it will start with ‘net.tcp://’.
Binding will typically start with ws or net. All bindings starting with ws will have text encoded message format (incuding the basicHttpBinding) and the bindings starting with net will have binary encoded message formats.

Typical way of defining Contracts
Contracts are usually defined via interfaces listing all the methods available to a remote client. However for distinguishing the interfaces meant to be contracts in WCF configuration, you must decorate the interface with [ServiceContract] attribute.
A Service Contract Interface may contain the definitions of multiple methods and not all methods may be meant for a remote client in some scenarios (usually that will be rare though). So only those methods which have [OperationContract] attribute on them will be available to remote client.
Data is exchanged between client and server via Method arguments (from client to server) and returned data of a method (server to client). Most of the types in .Net framework are serializable. However when exchanged data of custom type (example object of Employee class defined in your application), it must be serializable. So you must have [DataContract] attribute on the class whose objects are transported between client and server. Again like serialization, some data of your class is not meant to be serialized so in that case, only the fields or automatic properties with [DataMember] attribute on them will be serialized.
For example to provide a news Service where objects of NewsArticle may be exchanged between two applications here is how we can define it.


[ServiceContract]

public interface INewsService

{

      [OperationContract]

      NewsArticle[] GetNewsForAllBrief();

      [OperationContract]
      string GetNewsDetails(int id);

[DataContract]
public class NewsArticle
{
      [DataMember]
      public int id { get; set; }
      [DataMember]
      public string HeadLine { get; set; }
      [DataMember]
      public string BodySummary { get; set; }
      [DataMember]
      public string Date { get; set; }
      public int AuthorId { get; set; }
      public bool Confidential { get; set; }
      public string BodyDetail { get; set; }
}


The contract has two methods, one which gets all the news in brief (without the details and hence BodyDetail, AuthorId and Confidential properties in the NewsArticle class don’t have DataMember attribute on it) and the other which gets details of a particular News identified via id by client.
Service will be basically the class which provides implementation of the above interface. That class may implement multiple contract interfaces. We will be seeing the class in our examples ahead.

HOSTING THE SERVICE

Let us create our first WCF example. In this example, we will host a service in IIS (but for testing purposes, we can do it under location File System which will work fine).

Create a new empty web site say named WCF-NewsService-IIS-Hosted. Add a new item of type ‘WCF Service’.

This will add IService.cs and Service.cs files in the App_Code folder. In the IService.cs file,delete the interface defined by default and replace it with the INewsService defined earlier in the document and also define the NewsArticle class in the same file.
In the Service.cs file, replace the class with following.

public class Service : INewsService
{
      List<NewsArticle> news = new List<NewsArticle>();
      public NewsService()
      {
             NewsArticle news1 = new NewsArticle { id = 1,
             BodySummary = "Body 1",
             BodyDetail = "Detail 1",
             HeadLine = "Headline 1",
             Confidential = false,
             AuthorId = 1,
             Date = DateTime.Now.AddHours(-3).ToShortDateString() };

            NewsArticle news2 = new NewsArticle { id = 2,
            BodySummary = "Body 2",
            BodyDetail = "Detail 2",
            HeadLine = "Headline 2",
            Confidential = false,
            AuthorId = 1,
            Date = DateTime.Now.AddHours(-6).ToShortDateString() };

            news.Add(news1);
            news.Add(news2);
     }

          public String GetTime()
          {
                    return DateTime.Now.ToString();
          }
          public NewsArticle[] GetNewsForAllBrief()
          {
                    return news.Where( n => n.Confidential == false).ToArray();
          }
          public String GetNewsDetails(int id)
          {
                    var article = news.First( n => n.id == id);
                    return article == null? "": article.BodyDetail;
          }
}

The Service is made accessible to client via an Svc file (NewsService.svc file in this case) which is also added when you add an item of type ‘WCF Service’. It is like asmx file in case of web services. It only contains a single line which specifies the name of the Class which has implemented contracts.

Try to ‘View in Browser’ of NewsService.svc file. If everything was done correct, you should see the description of the Service in the browser.
(Note: If you are using Visual Studio 2008, you need to make changes in the configuration file in the system.ServiceModel section and rename the interface name and Service name if required)
In framework 4.0, when hosting in IIS, WCF assumes a default endpoint automatically and you don’t need to add any endpoint for the Service whose address is same as your website address, binding used is basicHttpBinding and contract is the one which Service has implemented. One more endpoint is automatically assumed which allows Service Metadata to be exchanged over Http protocol. This endpoint has relative address ‘Mex’, the binding is mexHttpBinding and the already defined IMetadataExchange contract. In case you need different settings, you must add endpoints for desired behavior.
Note: Keep the service application running. Don’t stop it.
Consuming Service
Now the service can be consumed by any application. Typically the service is consumed by creating a proxy of the service by creating proxy from WSDL of the service. Visual Studio makes it possible to automatically do that part for you when developing consumer code
Follow these steps to create the consumer
Open another Visual Studio and create a Console Application by the name ‘WCFConsumer’.
We need to create a proxy class to access the Web Services. To do this, right click on the project name and click on ‘Add Service Reference’ We need to specify the location of the service. Copy the Url from the browser where you have NewsService.svc.and paste it in the location textbox. Put ‘MyService’ in the namespace Textbox and press OK.
Visual Studio has now created a proxy class and also downloaded the definition of the NewsArticle class that will be returned and put them in the namespace WCFConsumer.MyService (As your project also has the namespace, what you type in namespace Textbox gets the project namespace as prefix to it).

Add the using WCFConsumer.MyService; directive to Program.cs.
Add the following code in the Main method

NewsServiceClient proxy = new NewsServiceClient();
foreach(var news in proxy.GetNewsForAllBrief() )
{
       Console.WriteLine("Headline : " + news.HeadLine + " , Summary :" + news.BodySummary + "        , Detail:" + proxy.GetNewsDetails(news.id));
}
Console.ReadLine();

Run the consumer application. You should see the list of News.

App.config file Configuration 

  <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="">
                    <serviceMetadata httpGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="false" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <services>
            <service name="Wcf_NewsService.NewsService">
                <endpoint address="NewsService" binding="basicHttpBinding" contract="Wcf_NewsService.INewsService">
                    <identity>
                        <dns value="localhost" />
                    </identity>
                </endpoint>
                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:8732/Design_Time_Addresses/Wcf_NewsService/NewsService/" />
                    </baseAddresses>
                </host>
            </service>
        </services>
    </system.serviceModel>