Building your first WCF application

WCF using C#: Building your first WCF application


Basic Concepts

  1. The WCF system contains:
  1. Client application
  2. Service .svc (Server application)
  3. Interface  - where the clients connects usually the interface is called something like Ixyz.WCF.Project  if the project is called xyz.WCF.Project
  4. Bindings  - describe the endpoints and protocols used
  5. Proxies  - hide the serialization details from the clients

Build a simple WCF app

First: Create a console application
  1. New project > Console Application
  1. Name it “ProductService” but change the SolutionName to “Products”


  1. What you should get:


  1. Right click on Products (the solution) > Add > New project > Console Application > ConsoleAplication and name it ProductsClient







  1. Next, add a new project of type ClassLibrary called ProductInterfaces







  1. The result:


  1. Git repository created - files saved


  1. Right click on the ProductService > Add > New item > Data > ADO .NET Entity Data Model


  1. Name the new item: ProductsModel

  1. Generate from database


  1. Create a new connection pointing to your database

  1. Select the Products database

  1. Test the connection


  1. The Wizard created the connection and the connection string



  1. Choose Entity Framework 6.x
  1. Pick the table
  1. Right click on the ProductService > Add > New Item > Click on Vicual C# Items > WCF Service
  1. Name the WCF Service: WCFProductService.cs

  1. WCFProductService created

  1. This is the service contract, it implements the WCFProductService (notice the colon)


  1. WCFProductService contains [ServiceContract] attribute and the [OperationContract] attribute - which is the operation that the client can perform
  1. The [OperationContract] attribute is the
  2. IWCFProductService.cs is the implementation of your service, we want to move it to the ProductInterfaces project so the client can have access to it
  3. Drag and drop the  IWCFProductService from the IWCFProductService.cs to ProductInterfaces project


  1. You need to delete it from the “server”  (the ProductService since it has just been copied)

  1. Since you have moved the IWCFProductService to a different namespace, you need to change that in IWCFProductService to ProductInterfaces




  1. Add System.ServiceModel (where the  WCF model lives) to references of the ProductInterfaces project


  1. Add reference to ProductInterfaces


  1. Remove void DoWork() in the IWCFProductService

  1. Replace it with List<string> ListProducts();

  1. Now we need to implement the above. In the WCFProductService remove the following:
  1. Right click on IWCFProductService and click on the Implement Interface


  1. Result



  1. Now - we need to host the service - in order to do that we need to edit ProductService \ Program.cs and create our host inside of the Main method

  1. Add System.ServiceModel to the ProductService project

using System.ServiceModel;



  1. Inside the Main method, add the following

using(ServiceHost host = new ServiceHost(typeof(WCFProductService)));



using (ServiceHost host = new ServiceHost(typeof(WCFProductService)))
        {
            host.Open();
            Console.WriteLine("Server is open");
            Console.WriteLine("<Press Enter to close the server>");
            Console.ReadLine("");
        }

  1. The host has been created, it will open, write two lines and wait for the user to close it  by pressing Enter
  2. The question now is: how will the host, know it’s contract. How it will know the address, the binding the protocol etc.  - We need to set up this information and we will store this information in the file called App.config

  1. Double click on the App.config, select the entire <system.serviceModel> tag and delete it:


  1. Right click on the App.config and select Edit WCF Configuration


  1. This will open the Microsoft Service Configuration Editor


  1. Click on Create a New Service  



  1. For the Service Type, select ProductService.exe in the productservice\bin\Debug directory
  1. So our service type = ProductService.WCFProductService
  2. Click Next
  3. What service contract are you using ? ProductService.IWCFProductService

  1. Click Next
  2. Leave the HTTP option selected and click Next
  1. Leave the Basic Web Services interoperability checked and click Next
  1. Specify the address for the endpoint:


  1. Press Next and Finish

  1. You should now see all the information Under Endpoints in the Microsoft Service Configuration Editor


  1. We can give the endpoint a name: ProductServiceEndPoint

  1. Go to File > Save and File > Exit

  1. Visual Studio will notice that the files have been changed and will give you a warning messages to which you should respond: Yes to All


  1. The App.config gets updated


  1. Now we will configure the client, click on the App.config in ProductClient


  1. Right click on App.config


  1. Click on Create a New Client
  1. Select Manually and hit Next
  1. Navigate to c:\tutorials\lessons\products\ProductInterfaces\bin\Debug

  1. Click Next
  1. HTTP
  1. Basic Web Services interoperability
  1. The Address of the endpoint should be the same as last time: http://127.0.0.1:7777/ProductService

  1. Name - leave (Default)
  1. You will get the summary


  1. Name the Client Endpoint: ProductServiceEndpoint




  1. Go to File > Save and File > Exit
  2. You should get a warning window  - click on Yes to All

  1. Your App.config should get updated


  1. To get the ProductInterface.IWCFProductService - you need to make sure that the namespace in IWCFProductService.cs has been changed to namespace ProductInterfaces also the using System.ServiceModel; needs to be added:

The code of the IWCFProductService.cs at the moment
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel;
namespace ProductInterfaces
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IWCFProductService" in both code and config file together.
[ServiceContract]
public interface IWCFProductService
{
    [OperationContract]
    List<string> ListProducts();
}
}


  1. Without the above - you may get a problem getting the right contract (in my case it was still contract="ProductService.IWCFProductService" instead of  ProductInterfaces)


  1. Let’s write an implementation of the ListProducts()
  2. Open the WCFProductService
  1. Erase: throw new NotImplementedException();

  1. Inside the curly brackets add the following:

List<string> productList = new List<string>();

  1. Type try and double click the tab button to get the try catch block

try
{
}
catch (Exception)
{
throw;
}


  1. Inside the try catch block type using > bracket and start typing prod - you should get a list of options - you should select the ProductEntities


using (ProductsEntities database = new ProductsEntities())

  1. The final code of public List<string> ListProducts()

public List<string> ListProducts()
{
Console.WriteLine("ListProducts() has been called by the client");
List<string> productList = new List<string>();
try
{
using (ProductsEntities database = new ProductsEntities())
{
var products = from p in database.Products select p.ProductID.ToString();
productList = products.ToList();
}
}
catch (Exception)
{
throw;
}
return productList;
}

  1. Now - move over to the ProductClient


  1. Add reference to System.ServiceModel
  1. Now we need to create the channel factory, basically we need to create our proxy which will take care of the connection to the service as vell as it handles the serialization behind the scenes
  2. Add the using System.ServiceModel;  - preprocessor directive (for some reason just adding the reference doesn’t bring the ChannelFactory references untill you explicitly add the using System.ServiceModel preprocessor directive)
  1. Add a reference to ProductInterfaces
  1. Add using ProductInterfaces; preprocessor directive (just adding a reference does not work for me)
  1. Type:
ChannelFactory<IWCFProductService> channelFactory = new ChannelFactory<IWCFProductService>(“”);

  1. Add the name of the endpoint from App.config as the parameter
  1. Result

ChannelFactory<IWCFProductService> channelFactory = new ChannelFactory<IWCFProductService>("ProductServiceEndpoint");

  1. Create a channel

IWCFProductService proxy = channelFactory.CreateChannel();


  1. Now you should be able to see what the service offers


  1. The final code of the ProductsClient.Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ServiceModel;
using ProductInterfaces;
namespace ProductsClient
{
class Program
{
    static void Main(string[] args)
    {
        ChannelFactory<IWCFProductService> channelFactory = new ChannelFactory<IWCFProductService>("ProductServiceEndpoint");
        IWCFProductService proxy = channelFactory.CreateChannel();
       
        //calls the server
        List<string> products = proxy.ListProducts();
           foreach (var p in products)
        {
            Console.WriteLine(p);
        }
Console.ReadLine();
    }
}
}

  1. The above code, calls the service it will extract the product list and return it to the client printing the results in the console - you can install the client on any machine in the world, it will connect to the given IP of your ProductService and get the data


  1. Now - right click on your Solution go to Preferences and set the Startup Project to Multiple startup projects - ProductInterfaces - None, ProductClient Start, ProductService Start
  1. Build and run the program
  1. If build succeeded then press Start
  1. Error

  1. I needed to reconfigure the bindings to Change the ProductService to ProductInterfaces


  1. This time when you build and click on start - the program worked properly


  1. So the program works fine, the only problem is we would like to see more information on the products
  2. Open WCFProductService.cs and change the query:

var products = from p in database.Products select p.ProductID.ToString() + " | " + p.ProductName + " | " + p.Price.ToString() ;


DOne

Comments

Popular posts from this blog

C# - Simple Class Library and how to use it in another project

AWS CLI - INSTALLATION AND CONFIGURATION

Upload a file to a Web server in ASP.NET by using Visual C# .NET