Sony Arouje

a programmer's log

Archive for the ‘WCF’ Category

Function returns Entity or DTO

with 2 comments

I am working on a project that deals WCF services. In our design we separated Entities and Datacontracts (DTO). The application layer takes care of converting Entities to DTO’s before passing it to Service layer. In the application layer, classes communicates and passes data but I need the inter application layer communication should deals with Entities not DTO’s. So I wanted to find a way so that the function can return Entity or DTO. In this post I will explain how I achieved it, It’s pretty simple.

One option is I could have moved the Entity to DTO mapping to Service layer. I decided not to do it and want to make the service layer light weight.

Another option is shown below.

Let’s take an example of POS system and here we deals with Product. For simplicity I takeout the Interface.

    public class ProductMaintenance
    {
        private Product _currentlyFetchedProduct;

        public ProductMaintenance Get(string productCode)
        {
            //do the logic to fetch product.
            return this;
        }

        public Product ToEntity()
        {
            return _currentlyFetchedProduct;
        }

        public ProductDTO ToDTO()
        {
            //do the logic to map Entity to DTO 
            return new ProductDTO();
        } 
    }

 

The Service class will make a call to the ProductMaintenance as shown below

ProductMaintenance productMaintenance = new ProductMaintenance();
return productMaintenance.GetProduct(productCode).ToDTO();

 

What if the ProductMaintenance class returns more than one type of Data, say it returns Product and List of Product. Then the complexity increases and difficult to handle it.

I introduced a new class to handle this situation called DataGetter, see the code below.

    interface IDataGetter<TSource, TDest>
        where TSource : class
        where TDest : class
    {
        TDest ToDTO();
        TSource ToEntity();
    }

    public class DataGetter<TSource, TDest> : IDataGetter<TSource,TDest>
        where TSource:class
        where TDest:class
    {
        private TSource _entity;
        public DataGetter(TSource entity)
        {
            this._entity = entity;
        }

        public TSource ToEntity()
        {
            return _entity;
        }

        public TDest ToDTO()
        {
            //Do the logic to convert entity to DTO
            return null;
        }
    }

Let’s rewrite the ProductMaintenance class with the new DataGetter.

        public IDataGetter<Product, ProductDTO> GetProduct(string productCode)
        {
            Product productFetched = Repository.GetProduct(productCode);
            return new DataGetter<Product, ProductDTO>(productFetched);
        }

        public IDataGetter<IList<Product>, IList<ProductDTO>> GetAll()
        {
            IList<Product> products = Repository.GetAllProducts();
            return new DataGetter<IList<Product>, IList<ProductDTO>>(products);
        }

The service can call the ProductMaintenance as shown below.

        public ProductDTO GetProduct(string productCode)
        {
            ProductMaintenance productMaintenance = new ProductMaintenance();
            return productMaintenance.GetProduct(productCode).ToDTO();
        }

        public IList<ProductDTO> GetAllProducts()
        {
            ProductMaintenance productMaintenance = new ProductMaintenance();
            return productMaintenance.GetAll().ToDTO();
        }

How to call ProductMaintenance from the same layer, that time we need to deal with Entity instead of DTO. We can easily do that by calling the same function chain with ToEntity() as shown below.

ProductMaintenance productMaintenance = new ProductMaintenance();
return productMaintenance.GetAll().ToEntity();

 

Another advantage of DataGetter is, we can abstract the Entity to DTO mapping from the application class. So any changes to the mapping provider can be done in a single place. For Entity mapping I use AutoMapper.

 

Word of Caution

If we are using any ORM with Lazy loading then make sure the repository session is opened till ToDTO or ToEntity call completes. Say for e.g. if we create the session in GetProduct and close the session in the finally, then ToDTO or ToEntity will throw error as the session is closed and unable to do Lazy loading. I use Castle Windsor to inject the repository dependencies and the session will get closed only in the Dispose function.

Written by Sony Arouje

February 20, 2013 at 8:53 pm

Posted in .NET, WCF

Tagged with ,

Diagnostic Trace (SVCLog) configuration for WCF

leave a comment »

Whenever I write any WCF service, I need to search in my snippets to find out the configuration to add Diagnostic traces for WCF. This post help me to pick the configuration any time when ever I need it.

  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel"
              switchValue="Information, ActivityTracing"
              propagateActivity="true">
        <listeners>
          <add name="traceListener"
              type="System.Diagnostics.XmlWriterTraceListener"
              initializeData= "F:\Sony\Traces.svclog" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>

 

Adding this configuration allows the WCF to log all the communication between the client and host in xml format. You can view svclog using SvcTraceViewer.exe, it shipped with Visual Studio and can found out in WCF installation location (C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin)

Written by Sony Arouje

November 10, 2011 at 2:34 pm

Posted in .NET, WCF

Tagged with , ,

WCF Duplex Communication with multiple clients

with 8 comments

Recent days I am working on a batch processing system to cater printing of more than 100k documents per day from a queue. To make system scalable I divided the system into two

Producer: who produce the document, it’s time consuming, CPU intensive process.
Consumer: who consumes the document and print/Email/fax it. Fairly simple with different handlers for printing, faxing or emailing and less CPU intensive

Producer and Consumer will communicate through a WCF service using TCPBinding.

One of the functionality of consumer is reporting the status (exception while printing) of the document back to the producer for audting purpose. My first design approach was
    Run these two system as a pair. The producer will call a WCF service hosted in consumer when a document is ready for printing and consumer will call a WCF service in producer to report the status.

If the document volume is high then user can configure and run multiple Producers and one consumer. That means each instance of producer, we need to provide unique endpoints. But producer can communicate to any one Consumer to status reporting thus by adding load to one of the Consumer.

If you think in terms of scalability/deployment you can visualize how complex the design will be. Yes I also realize that my design is ridiculous. To make it more scalable, I have to redesign the communication between the Consumer and the Producer.

This time I thought of trying Duplex communication for the first time. Initially I avoid duplex binding in first place because I don’t know it, second a bit scared of introducing complexity. In my mind duplex binding is complex and my approach I explained above is simple 🙂 (how ignorant I am).

So I decided to try duplex communication. But I need to evaluate it and don’t want to mess with my current implementation. So end up in writing a small tracer to experiment duplex communication. Rest of the post will go through the tracer I created.

Note: My design is surrounded with the proxy less communication approach.

Let’s start with the Service contract and Callback contract.

[ServiceContract (SessionMode=SessionMode.Required,CallbackContract=typeof(ICallbackInterface))]
public interface IServiceContract
{
    [OperationContract (IsOneWay=true)]
    void MessageToProcess(ServiceMessage message);
}

 

As you can see I mentioned the type of callback contract in ServiceContract attribute. The above contract will be implemented in Consumer and Producer will call the consumer using this contract if any thing available for processing.

public interface ICallbackInterface
{
    [OperationContract(IsOneWay=true)]
    void ProcessedMessage(ServiceMessage message);
}

The above callback interface will be implemented in Producer. Consumer will callback the Producer and update the status using this contract.

ServiceMessage is just a value object to transfer data between consumer and producer. It has just one string field called Message.

Let’s implement the Service contract in one of the class in Consumer.

[ServiceBehavior (InstanceContextMode=InstanceContextMode.PerSession)]
public class MessageProcessingService:IServiceContract 
{
    private ICallbackInterface GetCurrentCallback()
    {
        return OperationContext.Current.GetCallbackChannel<ICallbackInterface>();
    }
    public void MessageToProcess(ServiceMessage message)
    {
        ProcessRequest procRequest = new ProcessRequest(this.GetCurrentCallback(), message);
        ProcessQueue.Add(procRequest);
    }
}

 

We need to decorate the MessageProcessingService with ServiceBehavior attribute as shown above, we cannot set that in config file.

GetCurrentCallback function will return the callback instance that is part of the service call.

MessageToProcess function will be called by Producer once it produce some message to process. As you can see I created a new object of ProcessRequest  with callback instance and message then add the ProcessRequest instance to a queue. I will explain why we need queuing system.

Why we need a Queue?

Think of a scenario where there are multiple Producers and single consumer. The single consumer may not able to process all the message received from multiple producers in real time. So all the message will be queued along with the callback instance. Consumer will process the item in the queue one by one and notify the producer once the processing is done. With this implementation we can have n number of producers and one consumer.

Process Request class

public class ProcessRequest
{
    private readonly ICallbackInterface _callbackInterface;
    private readonly ServiceMessage _message;
    public ProcessRequest(ICallbackInterface callbackInterface, ServiceMessage message)
    {
        _callbackInterface = callbackInterface;
        _message = message;
    }

    public ICallbackInterface GetCallback()
    {
        return _callbackInterface;
    }

    public ServiceMessage GetMessage()
    {
        return _message;
    }
}

 

ProcessQueue implementation as follows

public static class ProcessQueue
{
    private static Queue<ProcessRequest> _processQueue;
    private static ManualResetEvent _enqueuedEvent;

    static ProcessQueue()
    {
        _processQueue = new Queue<ProcessRequest>();
        _enqueuedEvent = new ManualResetEvent(false);
    }

    public static void Add(ProcessRequest request)
    {
        lock (_processQueue)
        {
            _processQueue.Enqueue(request);
            _enqueuedEvent.Set();
        }
        ProcessQueuedItem();
    }

    private static ProcessRequest _currentRequest;
    public static bool Dequeue()
    {
        lock (_processQueue)
        {
            if (_processQueue.Count > 0)
            {
                _enqueuedEvent.Reset();
                _currentRequest = _processQueue.Dequeue();
                return true;
            }
            else
                return false;
        }
    }

    private static void ProcessQueuedItem()
    {
        while (Dequeue())
        {
            ServiceMessage message = _currentRequest.GetMessage();
            message.Message += " {Processed}";
            _currentRequest.GetCallback().ProcessedMessage(message);
        }
    }
}

 

ProcessedQueuedItem function process the message, for my tracer I just appended ‘{Processed}’ at the  message.

We are done with the Consumer implementation. Let’s go through the Producer.

public partial class frmProducer : Form
{
    public frmProducer()
    {
        InitializeComponent();
        this.Text = this.Text+ RandomGenerator.GetRandom().ToString();
    }

    private void btnSend_Click(object sender, EventArgs e)
    {
        ServiceMessage message = new ServiceMessage();
        message.Message = txtMessage.Text;
        InstanceContext instanceContext = new InstanceContext(new CallbackHandler());
        IServiceContract service = ServiceFactory.CreateInstance<IServiceContract>(instanceContext);
        service.MessageToProcess(message);
    }
}

 

As you can see in btnSend_click we need to create instance of InstanceContext with an instance of class that implemented ICallbackInterface I created earlier. Then I call a factory class to get the channel to Consumer. In the factory I used DuplexChannelFactory instead of ChannelFactory.

CallbackHandler implementation

public class CallbackHandler:ICallbackInterface
{
    public void ProcessedMessage(ServiceMessage message)
    {
        //do the status reporting here.
    }
}
 

We are done with our Producer and consumer implementation. We can test it by running different instance of Producer and one instance of consumer and see how the communication works.

Once my tracer is successful I redesigned the communication of Producer and Consumer in my projects with few changes of code. With new design user can add any number of Producer just by creating an instance of Producer without any difficulty.

Hope this little post will help some one who is new to duplex communication in WCF.

Download tracer source code (WCF.TCPIP.Duplex.Service) here

Written by Sony Arouje

September 29, 2011 at 1:56 am

Hosting Pipe/TCP based WCF service in Windows Activation Service

with 8 comments

In this post I will give a brief idea of how to host pipe/TCP based WCF service using WAS. Before WAS, we host TCP/pipe based service using custom hosting. That means we need to write an application ourself to host our services. Including me most of the deves wrote applications to host WCF services, so am not going in detail of custom hosting.

What’s WAS or Windows Process Activation services? WAS is part of IIS that enable us to host non http based services. I am not going much details of WAS. Here I am more concentrating on how to configure WAS and run a small test application.

Configure WAS in our System

By default WAS will be disabled. We need to enable it our self, let’s see how we can do that.

1. Goto control panels –> Programs and Features. Click on ‘Turn Windows Feature on or off’ link. It will open a window as shown below. From the list select Windows Process Activation Service and make sure all the child elements also selected.

image

2. Also scroll up and Select ‘Microsoft .NET Framework 3.xxx’ as shown below. Make sure all the child elements also selected, if not select it.

image

We enabled Windows Activation Service in our system. Let’s go ahead and create a WCF service.

For testing purpose I created a WCF service to add two numbers. Let’s see the service configuration

  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>          
        </behavior>
        <behavior name="calcServiceBehaviour">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
        </behavior>    
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    <services>
      <service name="ServiceLayer.CalculatorService" behaviorConfiguration ="calcServiceBehaviour">
        <endpoint name="CalculatorService" address="" binding="netTcpBinding"
                  contract="ServiceLayer.ICalc" />
        <endpoint name="CalculatorService" address="" binding="basicHttpBinding"
          contract="ServiceLayer.ICalc" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
  </system.serviceModel>

As you can see I have two endpoints HTTP and TCP. If we host this in IIS and try to browse it will throw error. Still some configuration is left behind. Let’s finish that config too.

Goto IIS configuration file. You can find that in C:\Windows\System32\inetsrv\config. Open applicationHost.config in notepad. You can see the screen shot below.

image

Search for bindings, and you can see the marked section as shown above. By default you could only see HTTP binding and rest of the binding you can add it. If other binding exist then we are good. If not copy paste the below bindings to the config file under Bindings section.

<binding protocol="net.tcp" bindingInformation="808:*" />

<binding protocol="net.pipe" bindingInformation="*" />

<binding protocol="net.msmq" bindingInformation="localhost" />

<binding protocol="msmq.formatname" bindingInformation="localhost" />

Next step is create an application in IIS. I named the application as Calculator. Right click on the newly created Application and select Manage Application –> Advanced Settings…, you will get a popup as shown below

image

In the above popup you need to enable the protocol this application going to support. As you can see the marked section, I added http, pipe and tcp protocols for my Calculator service. We can enter the protocols like http,net.pipe,net.tcp (separated by comma).

Once again go back to applicationHost.config file and verify the Sites section. You can see the newly created site with protocols it supports. See the screen shot below

image

We are done with our configuration and the service is ready. Lets go ahead and browse our svc file. If it’s not throwing any error then we are good to go.

Note: If we install IIS after the installation of Visual studio then it will throw some an error like Error 500.21 Handler "svc-Integrated" has a bad module "ManagedPipelineHandler" in its module list". If you are getting this error then run aspnet_regiis.exe –i  in VS command prompt.

Create an application to test our service, I created a winform app to test it. Also we need to create a proxy to access the service. We can create the proxy using svcutil. The util will create a config file as well as shown below.

  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="CalculatorService1" closeTimeout="00:01:00" openTimeout="00:01:00"
            receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
            bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
            maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
            messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
            useDefaultWebProxy="true">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
              maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="None">
            <transport clientCredentialType="None" proxyCredentialType="None"
                realm="" />
            <message clientCredentialType="UserName" algorithmSuite="Default" />
          </security>
        </binding>
      </basicHttpBinding>
      <netTcpBinding>
        <binding name="CalculatorService" closeTimeout="00:01:00" openTimeout="00:01:00"
            receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false"
            transferMode="Buffered" transactionProtocol="OleTransactions"
            hostNameComparisonMode="StrongWildcard" listenBacklog="10"
            maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10"
            maxReceivedMessageSize="65536">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
              maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <reliableSession ordered="true" inactivityTimeout="00:10:00"
              enabled="false" />
          <security mode="Transport">
            <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
            <message clientCredentialType="Windows" />
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
    <client>
      <endpoint address="net.tcp://sonyarouje/Calculator/CalculatorService.svc"
          binding="netTcpBinding" bindingConfiguration="CalculatorService"
          contract="ICalc" name="CalculatorService">
        <identity>
          <servicePrincipalName value="host/sonyarouje" />
        </identity>
      </endpoint>
      <endpoint address="http://localhost/Calculator/CalculatorService.svc"
          binding="basicHttpBinding" bindingConfiguration="CalculatorService1"
          contract="ICalc" name="CalculatorService1" />
    </client>
  </system.serviceModel>

 

Add an app.config to our test app and copy paste the config generated by svcutil. As you can see we have two endpoint http and tcp and we can use any of those. I called the service in button click and the code is as follows

CalcClient calc = new CalcClient("CalculatorService");
int x = Convert.ToInt32(txtX.Text);
int y = Convert.ToInt32(txtY.Text);
MessageBox.Show (string.Format("Sum is {0}", calc.Sum(x,y )));
calc.Close();

While creating the object of service proxy we can pass the endpoint name. Here I am passing CalculatorService and it is the name of tcp endpoint. So the communication will establish through TCP. If we pass CalculatorService1 it will use the http end point.

Hope my post will be helpful for some one. if any Comments or Suggestion, pls post it in the comment section.

Download Test Projects

Written by Sony Arouje

April 3, 2011 at 3:19 pm

Posted in .NET, WCF

Tagged with , , , ,

Photo Album using Silverlight,Caliburn Micro and MongoDB–Part 2

with one comment

This post is a continuation to my another post about a photostream application in Silverlight 4. You all can read more about the post here. I publish the code to codeplex with some more updates. The functionalities added to application is as below

  • Add/Delete Categories
  • Public commenting for Photos
  • Delete Photo
  • Filter photo’s based on Category

Below are some of the functionality in the app.

Home Page

Home

The home page will display the thumbnails of all your photos. In the right hand pane you can see the list of categories I created. User can see the photos in a particular category by clicking the category. You can add category by clicking on the Add/Edit category in the right hand side.

Photo Preview

PreviewPhoto

Nothing much to say it just show a preview of your photo. As you can see there are some icons at the bottom of the preview window. One for adding/viewing comments and another for deleting the photo. You might wonder how a public user can delete a photo. No they can’t am working on the admin part once it’s added only the admin user can do the delete and other admin related functionalities.

Public Comment(s)

PhotoComments

Clicking on the small icon next to the delete button will show the comments as well as user can add comments.

Upload Photos

UploadPhoto 

You can upload multiple photos at a time. Currently assigning a photo to category can be done at the time of uploading.

Hope this app will be helpful for some one.

Download Source code.

Written by Sony Arouje

November 28, 2010 at 12:56 am

Image uploading & Retrieving – Silverlight and WCF

with 9 comments

In several forums I saw people asking about how we can upload Images or files to server using silverlight. So I thought of writing one to demonstrate how we can achieve it. I become a big fan of caliburn micro and I used it in this app as well.

In this demo app I demonstrating both approach of accessing WCF service – Proxy less and Proxy approach. I personally like Proxy less approach so I cannot avoid it here also.

Let’s go through my solution structure

image

Repository: This project contains entities and persistence classes. I made it as simple as possible in this demo, so all the persistence related stuff is in the same project.

WCFService: Project contains the service implementation

WCFService.Interfaces: project contains the service contracts.

WCFHost: Project host the WCF service.

In Silverlight folder I have a Project called ServiceLinkProject, that is a project that has link to entity files. It is used for Proxy less WCF communication. In this demo I used my generic repository mentioned in my previous post.

There is nothing much to explain here except the valueconverter I used in the xaml page. I save and retrieve images as byte arrays. But silverlight’s Image control will not be able to render byte arrays. So wrote a Converter inherited from IValueConverter. Let’s see how am using it.

First I created an instance of the converter.

    <navigation:Page.Resources>
        <converter:ByteToImageConverter x:Name="binaryConverter"/>
    </navigation:Page.Resources>

 

Now use this converter while binding the byte[] to image.

<Image x:Name="thumbNail"  Width="100" Height="100" VerticalAlignment="Center" Source="{Binding ImageInBytes,Converter={StaticResource binaryConverter}}"></Image>


I think this project doesn’t requires much explanation. If any one has any questions then am happy to help you out.

Download Source code

Written by Sony Arouje

October 16, 2010 at 4:04 am

Proxy less Silverlight – WCF Async communication

with 12 comments

In this post I am going to explain how a silverlight application can communicate with WCF service without any proxy. I wanted to establish this communication without any autogenerated code because am not a fan of proxies generated by VS. If you want VS to create good autogenerated code then probably invest some time in learning T4 templates. Anyway I haven’t done any research in T4 templates, so let’s do every thing by hand.

Here is my requirement, I have to show a list of customer in my Silverlight app. Keep in mind it just an experiment, so no db involved in this app. For simplicity I hosted my wcf service in IIS.

Let’s straight to the code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using DataModel;
namespace ServiceContracts
{
    [ServiceContract]
    public interface ICustomerService
    {
        [OperationContract]
        ICollection<Customer> GetCustomerList();
    }

}

I only have one function in the service contract, a function return a collection of Customer class. Customer class is a just a C# class that has only two properties as shown below

using System.Runtime.Serialization;
namespace DataModel
{
    [DataContract]
    public class Customer
    {
        [DataMember]
        public int CustomerId { get; set; }

        [DataMember]
        public string CustomerName { get; set; }
    }
}
Let’s give some implementation to our Service Contract
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ServiceContracts; //assembly consist service contracts
using DataModel; //assembly contains data contracts
namespace ServiceLayer
{
    public class CustomerService:ICustomerService
    {
        public ICollection<Customer> GetCustomerList()
        {
            List<Customer> customers = new List<Customer>();
            Customer cust = new Customer();
            cust.CustomerId = 1;
            cust.CustomerName = "sony";

            customers.Add(cust);
            return customers;
        }

        }

}

 

Now our service is ready to host, here I use IIS to host it. But how does Silverlight can utilize the Function we implemented, because I haven’t implemented Async methods. You might know that Silverlight can only work in Async mode. There are several ways of calling the above implemented service in Silverlight. One way is adding Service reference and leave it to VS to create the proxy with Async code generation. Another approach is use Castle Windsor to host the service in Async mode. Some how I didn’t like both the approach so I was trying for a better approach. My search ended up in a blog to achieve the Async communication without much modification to my Service code.

Here is the approach I was looking at. Create a new Service contract with Async functions and make it an alias to my original ICustomerSerivce

[ServiceContract(Name = "ICustomerService")]
public interface ICustomerServiceAsync
{
    [OperationContract(AsyncPattern = true)]
    IAsyncResult BeginGetCustomerList(AsyncCallback callback, object state);

    ICollection<Customer> EndGetCustomerList(IAsyncResult result);
}

 

And use the above ICustomerServiceAsync to communicate to ICustomerService. This approach is pretty clean and we don’t want to add any Async methodology to our core service.

Below is my web.config of WCFService host.

<?xml version="1.0"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="CustomerService">
        <endpoint address="" contract="ServiceContracts.ICustomerService" binding="basicHttpBinding"></endpoint>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>  
</configuration>

 

As you see my service end point configuration I have not mentioned ICustomerServiceAsync. Let’s go through the silverlight client how we can communicate to our service.

private void button1_Click(object sender, RoutedEventArgs e)
{
    EndpointAddress endPoint = new EndpointAddress("http://localhost:63301/CustomerService.svc");
    BasicHttpBinding binding = new BasicHttpBinding();
    ICustomerServiceAsync customerService = new ChannelFactory<ICustomerServiceAsync>(binding, endPoint).CreateChannel();

    customerService.BeginGetCustomerList(a => 
    {
        try
        {
            ICollection<Customer> person = customerService.EndGetCustomerList(a);
        }
        catch (Exception ex)
        {
            throw ex;
        }

    }, customerService);

}

In a button click am calling the service.  Here I used the ICustomerAsync to create the channel. Ayende’s blog will give you more details.

You might think how I could able to reference ICustomerServiceAsync and Customer classes in my Silverlight client. What I did here is I created a Silverlight class library and add ICustomerAsync and Customer class as a link. In VS we can do it by selecting add existing item and rather than clicking on the Add button, click on the arrow on the right side of the Add and select as link from the option.

In the above client code I used lambda expression to call the service. You can also use a anonymous delegate or Callback method to achieve the same.

One important thing you need to add to our WCFService host project is clientaccesspolicy.xml, other wise Silverlight client will not be able to communicate and throws Security exception. Below is the policy file

<?xml version="1.0" encoding="utf-8"?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-request-headers="*">
        <domain uri="*"/>
      </allow-from>
      <grant-to>
        <resource path="/" include-subpaths="true"/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>

 

To test my connection and exceptions I used a Winform application. Silverlight wont give proper error details.

Download the code here

 

 

Written by Sony Arouje

October 1, 2010 at 7:14 pm

WCF Hosting an easy method

with 2 comments

My current project is based on WCF service. One of my responsibility is to find a method to host the WCF service. I googled a lot and failed to find one. Every site mentioned about creating ServiceHost instance one by one and call the open method on all service. The disadvantage of this method is we need to add a ServiceHost instance when ever we add a new service to the hosting application. Thus by modifying the service host application

So I come across with an idea of a method to read the Service configuration and host each service. Following is the method I created.

using System.Xml.Linq;

private static List<Type> ServiceHostHelper()
{
    XDocument configXML = XDocument.Load(“ServiceHost.exe.config“); //load the app config file to read using LINQ.
    var configs = (from config in configXML.Descendants(“service”)
                       select new AssemblyDetails
                       {
                           ActivatorClass = config.Attribute(“name”).Value
                       }
                   );

    Assembly assembly;
    assembly = Assembly.LoadFrom(“AddressMngr.dll”);
    List<Type> assmTypes = new List<Type>();
    foreach (AssemblyDetails assm in configs)
    {

//reflection to get the type of the service.         
        Type type = assembly.GetType(assm.ActivatorClass);         assmTypes.Add(type);
    }
    return assmTypes;
}

AssemblyDetails is my class to store the name of the service class. Below is the class

public class AssemblyDetails
{
    string _activatorClass;
    string _fullPath;
    public string ActivatorClass
    {
        get { return _activatorClass; }
        set { _activatorClass = value; }
    }
    public string FullPath
    {
        get { return _fullPath; }
        set { _fullPath = value; }
    }
}

Now lets see how I host the service. Here I host service using a console application

static void Main(string[] args)
{
    List<Type> services = ServiceHostHelper(); // services object will have all the services we defined in the app.config

    ServiceHost[] hostApp = new ServiceHost[services.Count];
    Console.WriteLine(“Following Services are Started”);
    for (int i=0;i<services.Count;i++)
    {

            Type service = services[i];
            hostApp[i] = new ServiceHost(service);
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine(service.ToString());

            hostApp[i].Open();
    }
    Console.ForegroundColor = ConsoleColor.Gray;
    string key=string.Empty ;
    do
    {
        Console.Write(“Type exit to terminate the host>”);
        key = Console.ReadLine();
        if (key == “exit”)
        {
            for (int i = 0; i < services.Count; i++)
            {
                hostApp[i].Close();
            }
        }
    } while (key != “exit”);
}

We also need to see how I configured the service. Here is my app.config configuration

<services>
  <service name=”AddressMngr.UserManager“>
    <endpoint address=”net.tcp://localhost:8001/UserManager”
              binding=”netTcpBinding”
              bindingConfiguration=”TransactionalTCP”
              contract=”AddressMngr.IUser”/>
  </service>
  <service name=”AddressMngr.Address” behaviorConfiguration=”ThrottledBehaviour”>
    <endpoint address=”net.tcp://localhost:8001/Address”
      binding=”netTcpBinding”
      bindingConfiguration=”TransactionalTCP”
      contract=”AddressMngr.IAddress”/>
  </service>
</services>

One thing we need to take care is the service name (marked in red) should be same as the class we implemented the Service contract with full name space. I am giving the fully qualified name is to load the class using reflection.

If you have any question then let me know, am happy to help you.

Technorati Tags: ,

Written by Sony Arouje

August 25, 2010 at 4:17 pm

Posted in WCF

Tagged with ,

%d bloggers like this: