Wednesday, April 4, 2012

WCF Data Service


WCF Data Service, enables the capability of exposing the entity objects as service objects and also the service methods can be invoked directly from the request url. The method of invoking the service method(s) from url is same as like in MVC invoking through url or same as like REST API.
Beside the possible way of invoking from browser, the same url can be treated as WCF Service and can be used to generate a proxy class in the client application adding through the service reference.
Below example demonstrates both of these.

WCF Data Service .cs
using System;
using System.Data.Services;
using System.Data.Services.Common;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.Web;
using CarModel;

public class WcfDataService : DataService<CarEntities>
{
    // This method is called only once to initialize service-wide policies.
    public static void InitializeService(DataServiceConfiguration config)
    {
        //setting access to read all the "AllCars" entity objects
        config.SetEntitySetAccessRule("AllCars", EntitySetRights.AllRead);

        //setting the access to invoke operations
        config.SetServiceOperationAccessRule("GetGermanCars",
                                      ServiceOperationRights.AllRead);
        config.SetServiceOperationAccessRule("GetJapaneseCars",
                                      ServiceOperationRights.All);
        config.SetServiceOperationAccessRule("AddJapaneseCar",
                                      ServiceOperationRights.All);
        config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
    }

    //can invoke the "GetGermanCars" method requesting from browser as
    //http://localhost:[port]/[webapp]/WcfDataService.svc/GetGermanCars?strModel='[value]'
    //or
    //http://localhost:[port]/[webapp]/WcfDataService.svc/GetGermanCars
    [WebGet]
    public string GetGermanCars(string strModel)
    {
        //getting the list of "AllCars" of type "German" and serializing in JSON format and returning the same
        IEnumerable<AllCar> GCars = null;
        if (string.IsNullOrEmpty(strModel))
            GCars = from a in this.CurrentDataSource.AllCars.OfType<GermanCar>() select a;
        else
            GCars = from a in this.CurrentDataSource.AllCars.OfType<GermanCar>() where a.Model == strModel select a;
        System.Web.Script.Serialization.JavaScriptSerializer objJavaScriptSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
        return objJavaScriptSerializer.Serialize(GCars);
    }

    [WebGet]
    public IQueryable<string> GetJapaneseCars(string strModel)
    {
        //getting the list of "AllCars" of type "Japan" returning the japan car models
        if (string.IsNullOrEmpty(strModel))
            return from a in this.CurrentDataSource.AllCars.OfType<JapaneseCar>() select a.Model;
        else
            return from a in this.CurrentDataSource.AllCars.OfType<JapaneseCar>() where a.Model == strModel select a.Model;
    }

    [WebGet]
    public IQueryable<string> AddJapaneseCar(string strModel, string strBrand)
    {
        //Adding "Japan" car to database with given model and brand
        JapaneseCar obj = new JapaneseCar() { Model = strModel, Brand = strBrand, JapaneseCarAdditionalNotes = "This is japenese car added via WCF Dataservice" };
        this.CurrentDataSource.AllCars.AddObject(obj);
        this.CurrentDataSource.SaveChanges();
        return from a in this.CurrentDataSource.AllCars.OfType<JapaneseCar>() where a.Model == strModel select a.Model;
    }
}

In Client Application
Program.cs

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

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                //require to add the "WCF Data Service" url as Service reference.
                //accessing the WCF data service
                EntityProxy.CarEntities objEntities = new EntityProxy.CarEntities(new Uri("http://localhost:44731/Misc/WcfDataService.svc/"));
                //getting the list of Entity objects (AllCars) and wtriting the model of the car to console
                IQueryable<EntityProxy.AllCar> cars = objEntities.AllCars;
                foreach (var item in cars)
                {
                    Console.WriteLine(item.Model);
                }
            }
            catch (Exception exp)
            {
                Console.WriteLine("Error : " + exp.Message);
            }

            Console.Read();
        }
    }
}

From Client (Console)


From Browser







 http://localhost:44731/Misc/WcfDataService.svc/GetJapaneseCars



No comments: