C#

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>

No comments:

Post a Comment