Software Architecture – Web Application optimization without code changes

November 11, 2011

Objective: Web Application optimization without code changes.
Strategy: Read all the references below and apply them in test lab. After clear understanding of domain, have access to Client machine and apply this checklist on client machine. Make sure to have backup strategy for client environment.
Guideline Points:
1. Log only essential information or completely disable IIS logging
2. Disable IIS ASP debugging in production environments
3. Tune the value of the ASP Threads Per Processor Limit property
4. Tune the value of the ASP Queue Length property
5. Tune the MaxPoolThreads registry entry
6. Disable WCF services tracing
7. Configure ASP.NET MaxConcurrentRequests for IIS 7.0 Integrated mode
8. Enable IIS HTTP compression
For point 1-8 see below reference)
(Reference: http://msdn.microsoft.com/en-us/library/ee377050(v=bts.10).aspx )

9. Configuring HTTP Compression in IIS 7
(Reference: http://technet.microsoft.com/en-us/library/cc771003(WS.10).aspx )

10. Configuring Output Caching in IIS 7
(Reference: http://technet.microsoft.com/en-us/library/cc732475(WS.10).aspx )

11. Follow this link:
http://learn.iis.net/page.aspx/93/optimizing-performance/

12. For web Pages add following tag.

Reference: http://msdn.microsoft.com/en-us/library/h30h475z(v=VS.100).aspx

13. Optimizing WCF Web Service Performance
http://msdn.microsoft.com/en-us/library/ee377061(v=bts.10).aspx

14. Few tips related to ASP .Net
http://madskristensen.net/post/Performance-tuning-tricks-for-ASPNET-and-IIS-7-part-1.aspx
http://madskristensen.net/post/Performance-tuning-tricks-for-ASPNET-and-IIS-7-e28093-part-2.aspx

15. Few tips related to ASP .Net
http://wiki.asp.net/page.aspx/31/performance/

16. For better performance, you should remove any HTTP Modules that you are not using.
Reference: http://aspadvice.com/blogs/ssmith/archive/2007/08/03/Real-World-ASP.NET-Performance-Tuning-Experience.aspx

17. Performance Tuning for Active Directory Servers (Important)
http://msdn.microsoft.com/en-us/windows/hardware/gg463394
[In this white paper, read Active Directory section.]

18. AD performance Tuning
http://blogs.technet.com/b/exchange/archive/2010/02/03/3409281.aspx
http://www.markwilson.co.uk/blog/2006/04/maximising-active-directory-performance.htm
http://technet.microsoft.com/en-us/library/bb123771(EXCHG.65).aspx

Advertisements

Software Architecture-Strategy for Performance tuning a .Net application

September 10, 2011

Strategy for Performance tuning a .Net application:
There are two parts to work in terms of performance tuning.
First part, is application specific optimization which refer to things required in terms of product under development. It requires deep product knowledge and code level awareness of product.
Second part, is technology specific optimization which refer to things provide by technology as tip to improve the performance.
For second part, following is list of acts to be taken.

1. Allocate a senior resource to act as PIG in SCRUM theory for this task.
2. Analyze the technologies used in application like c#, .Net, ASP .Net, WCF, MVC, IIS. Identify set of checklist which needs attention to be verified in application.
3. First step would be to review code in application. Second step would be to apply the checklist identified in step 2.
4. Bench mark the effect of each change in application (checklist) to analyze the performance.
5. QA team member can really help in it.

Online References for implementing checklist:

C# Performance:
Microsoft:
http://msdn.microsoft.com/en-us/magazine/cc500561.aspx
http://msdn.microsoft.com/en-us/library/ff647813.aspx
http://msdn.microsoft.com/en-us/library/ms973839.aspx
http://msdn.microsoft.com/en-us/library/ms973839
http://msdn.microsoft.com/en-us/library/ms973852
http://msdn.microsoft.com/en-us/magazine/cc163510.aspx
http://msdn.microsoft.com/library/ms973837.aspx
http://msdn.microsoft.com/library/ms973858.aspx

Others:
http://www.techgalaxy.net/Docs/Dev/5ways.htm
http://www.codeproject.com/KB/cs/effective1.aspx

Blogs:
http://blogs.msdn.com/b/ricom/

ASP .Net Performance:
http://msdn.microsoft.com/en-us/magazine/cc163854.aspx
http://msdn.microsoft.com/en-us/library/ff647787.aspx
http://www.codeproject.com/KB/aspnet/10ASPNetPerformance.aspx
http://www.realsoftwaredevelopment.com/20-tips-to-improve-aspnet-application-performance/
http://wiki.asp.net/page.aspx/31/performance/

WCF Performance:
http://support.microsoft.com/kb/982897
http://msdn.microsoft.com/en-us/library/ee377061(v=bts.10).aspx
http://msdn.microsoft.com/en-us/library/ms735098.aspx

Blogs:
http://www.askives.com/wcf-performance.html
http://blog.thekieners.com/2010/05/04/optimize-data-contracts-for-better-wcf-performance/
http://merill.net/2008/10/wcf-performance-optimization-tips/
http://weblogs.asp.net/sweinstein/archive/2009/01/03/creating-high-performance-wcf-services.aspx
http://metallemon.hubpages.com/hub/WCF-Service-Performance
http://www.aspnet101.com/2010/08/wcf-performance-best-practices/
http://blogs.msdn.com/b/stcheng/archive/2011/01/05/wcf-wcf-performance-testing-information-share.aspx
http://webservices20.blogspot.com/2009/01/wcf-performance-gearing-up-your-service.html
http://blogs.msdn.com/b/wenlong/archive/2007/10/27/performance-improvement-of-wcf-client-proxy-creation-and-best-practices.aspx

MVC Performance:
http://www.codeproject.com/KB/aspnet/How_to_improve_performanc.aspx
http://weblogs.asp.net/gunnarpeipman/archive/2010/02/07/asp-net-mvc-performance-ii-optimizing-resources.aspx
http://www.slideshare.net/rudib/aspnet-mvc-performance
http://msmvps.com/blogs/kenlin/archive/2010/05/14/mvc-performance-in-iis-part-ii.aspx
http://blogs.msdn.com/b/marcinon/archive/2011/02/07/mvc-performance-tips.aspx


Software Architecture – RESTful WCF Services for .Net Framework 4.0/Visual Studio 2010

May 14, 2011

According to Wiki, Restful Webs services are described as:

A RESTful web service (also called a RESTful web API) is a simple web service implemented using HTTP and the principles of REST. It is a collection of resources, with three defined aspects:
•the base URI for the web service, such as http://example.com/resources/
•the Internet media type of the data supported by the web service. This is often JSON, XML or YAML but can be any other valid Internet media type.
•the set of operations supported by the web service using HTTP methods (e.g., POST, GET, PUT or DELETE).

For programming Restful services in .Net Framework, till visual studio 2008 sp1, there was a separate kit for named “WCF REST Starter Kit Preview 2” at:
http://aspnet.codeplex.com/releases/view/24644

But it was not upgraded for Visual studio 2010. So for Visual studio 2010/.Net 4.0, search WCF+REST related items in Visual studio gallery.

http://visualstudiogallery.msdn.microsoft.com/site/search?f%5B1%5D.Type=SearchText&f%5B1%5D.Value=WCF%20REST%20Service&f%5B0%5D.Value=templates&f%5B0%5D.Type=RootCategory

One of the best template by WCF Team in Microsoft is as below:

http://visualstudiogallery.msdn.microsoft.com/fbc7e5c1-a0d2-41bd-9d7b-e54c845394cd

Download file named “WcfRestService40(CS).vsix”, and double click to install the template.

Now a new project type named “WCF REST Service application” is added.

I created a new project based on new project type named “WcfRestServiceApp”.

Added a console project to solution for running service named “ServiceServerApp”, with following code

WcfRestServiceApp.Service1 serv = new WcfRestServiceApp.Service1();
            WebServiceHost host = new WebServiceHost(serv, new Uri("http://localhost/WCFRESTService/"));
            host.Open();
            Console.WriteLine("Service is running....Press enter to stop the service...");
            Console.Read();
            host.Close();

When you try to run service, you will get following error:

In order to use one of the ServiceHost constructors that takes a service instance, the InstanceContextMode of the service must be set to InstanceContextMode.Single.  This can be configured via the ServiceBehaviorAttribute.  Otherwise, please consider using the ServiceHost constructors that take a Type argument.

As error explains, I have to change InstanceContextMode from InstanceContextMode.PerCall
to InstanceContextMode.Single

After that I got following error:

HTTP could not register URL http://+:80/WCFRESTService/. Your process does not have access rights to this namespace (see http://go.microsoft.com/fwlink/?LinkId=70353 for details).

So solution is to run following command incase of windows 7.

netsh http add urlacl url=http://+:80/WCFRESTService/  user=juliet\shah

For theory details see the link above.

So I am ready with service running .

While analyzing code of template, two things are important to note.
•Template uses the WebGetAttribute and WebInvokeAttribute to associate service operations with both GET and other HTTP verbs like PUT, POST, and DELETE.
•Template uses the UriTemplate and UriTemplateTable classes to provide URI processing capabilities.
For details about theory visit following
http://msdn.microsoft.com/en-us/library/bb412172.aspx

That all from my side for RestFull web Services in .Net framework 4.0/Visual studio 2010


Software Architecture – WCF Web services – Non windows based Security

January 9, 2011

Exploration Note

By: Shahzad Sarwar
Date: 7th Jan 2011

Problem definition:
WCF Web services are deployed with IIS as Host. Security implementation is required with following limitations.
1. Windows based authentication is not available.
2. Service may be deployed on system outside the forest and client inside the forest of Active directory.
3. Only Authentication aspect of security.
Environment:
.Net 3.5, WCF Services, IIS


Software Architecture – Exception -MaxArrayLength property on the XmlDictionaryReaderQuotas object

August 5, 2010

Environment:
Visual Studio 2010/C# 4.0, WCF, NHibernate, Silverlight 4
Exception:
While uploading a file by converting file content into array of bytes and sending it to server side via WCF, generates following exception.

The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:***. The InnerException message was ‘There was an error deserializing the object of type ****. The maximum array length quota (16384) has been exceeded while reading XML data. This quota may be increased by changing the MaxArrayLength property on the XmlDictionaryReaderQuotas object used when creating the XML reader. Line 1, position 57216.’.

Solution:
If you search XmlDictionaryReaderQuotas in object browser, you will find as:



So there is a configuration option in Servicemodel configuration, for setting the maximum array size limit. You can change the default limit of maxArrayLength tag by adding following XML in Service configuration of WCF Service as:

<bindings>
        <basicHttpBinding>
          <binding
                   maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" closeTimeout="0:50:0" openTimeout="0:50:0" receiveTimeout="0:50:0" sendTimeout="0:50:0"                  
                   >
            <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="2097152"  maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          </binding>

          </basicHttpBinding>
</bindings>

Reference:
http://msdn.microsoft.com/en-us/library/system.servicemodel.basichttpbinding.readerquotas.aspx


Software Architecture – Design Problem Part 2 – DTO- MS Visual Studio 2010 – Net 4-0 – WCF – NHibernate – Silverlight

July 31, 2010

This is second post with reference to Design Architecture discussion on Project based on NHibernate + WCF+Sliverlight.
See the first Post last post here.

In my last post I had identified that we need DTO Objects.
DTO-Data Transfer Objects are customized object that can have different object structure then Objects used in OR Mapping/Nhibernate. When a request for object comes from client (Silverlight project) to server (ASP .Net project) having Service via WCF wire, at Server side, query is run on OR Mapping Object, utiizing full benefits of Lazy loading, business rules are applied, and finally data is ready to be send to client. At this point data is not in customized according to client needs and filtering of properties for objects is required to reduce the size of data being transferred. That where DTO objects comes in action.

Benefits of DTO objects:

1. It is always better from software design perspective to not expose object of data layer direct to client end that is silverlight via WCF.

2. Most important benefit is: filtering of object properties or Change in structure of objects that needs to be transferred across WCF wire. Let suppose you have invoice creation form having fields to be filled as like client, consignee, agent, shipper, sales person, operation manager and many other. So when loading invoice form data from all these entities like agents ……. will travel on WCF wire. Each entity may have a lot of properties, but on client side we only need id and name of all these entities. So we can make various versions of entities according to need for architecture.

3. With DTO approach, UI (silverlight) is only dependent on DTO objects, so the data layer can be changed to any tech like linq2sql,linq2entities or any other thing. Change in Data layer is very flexible with DTO.

Elements of Design Example:
You can download sample here.
Rename the file as sample.zip and then extract.

Solution Explorer will look like as:



This Example will fetch 2 different DTO objects with sample look and feel as below.


There is one entity class for nhibernate named as “Customer” with HBM set in Mapping.hbm.xml.

There are 2 DTO Classes. First DTO with properties as ClientID,ClientCode, Name.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.Serialization;

namespace WCFNHibernateSilverLightSample.Web.DTOEntities
{
    [DataContract(IsReference = true)] 
    public class DTOCustomer
    {
        #region Fields
        private int _ClientID;
        private string _ClientCode;
        private string _Name;
        #endregion
        #region Constructors
        /// <summary>
        /// Initializes a new instance of the GeneralClientMaster class 
        /// </summary> 
        public DTOCustomer()
        {
        }     
        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets the ClientID for the current GeneralClientMaster
        /// </summary>
        [DataMember]
        public virtual int ClientID
        {
            get { return _ClientID; }
            set { _ClientID = value; }
        }

        /// <summary>
        /// Gets or sets the ClientCode for the current GeneralClientMaster
        /// </summary>
        [DataMember]
        public virtual string ClientCode
        {
            get { return _ClientCode; }
            set { _ClientCode = value; }
        }
        [DataMember]
        public virtual string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }

        #endregion

    }

    
}

Second DTO class has extra parameter of Address as:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.Serialization;

namespace WCFNHibernateSilverLightSample.Web.DTOEntities
{
    [DataContract(IsReference = true)]
    public class DTOCustomerVersionWithAddress
    {
        #region Fields
        private int _ClientID;
        private string _ClientCode;
        private string _Name;
        private string _Address;
        #endregion
        #region Constructors
        /// <summary>
        /// Initializes a new instance of the GeneralClientMaster class 
        /// </summary> 
        public DTOCustomerVersionWithAddress()
        {
        }
        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets the ClientID for the current GeneralClientMaster
        /// </summary>
        [DataMember]
        public virtual int ClientID
        {
            get { return _ClientID; }
            set { _ClientID = value; }
        }

        /// <summary>
        /// Gets or sets the ClientCode for the current GeneralClientMaster
        /// </summary>
        [DataMember]
        public virtual string ClientCode
        {
            get { return _ClientCode; }
            set { _ClientCode = value; }
        }
        [DataMember]
        public virtual string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }
        [DataMember]
        public virtual string Address
        {
            get { return _Address; }
            set { _Address = value; }
        }

        #endregion

    }
 
}

A converter class will be required as below to transform “customer” to “DTOCustomer” and “DTOCustomerVersionWithAddress”.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WCFNHibernateSilverLightSample.Web.DTOEntities.DTOConvertor
{
    public class DTOConvertor
    {
        #region CustomerConvertor

        public static DTOCustomer ConvertFromCustomerToDTOCustomer(Customer cust)
        {
            DTOCustomer dtocus = new DTOCustomer();
            dtocus.ClientID =  cust.ClientID;
            dtocus.ClientCode =  cust.ClientCode;
            dtocus.Name =  cust.Name;            
            return dtocus;            
        }
        public static DTOCustomerVersionWithAddress ConvertFromCustomerToDTOCustomerVersionWithAddress(Customer cust)
        {
            DTOCustomerVersionWithAddress dtocus = new DTOCustomerVersionWithAddress();
            dtocus.ClientID = cust.ClientID;
            dtocus.ClientCode = cust.ClientCode;
            dtocus.Name = cust.Name;
            // Note here Transformation of properties from Nhibernate Object to DTO Objects
            // It is really a simple example. Very advance level tranformation can be done.
            dtocus.Address = cust.PostalAddress + " Tel: " + cust.Phone1 + " Fax: " + cust.Fax1 + " Email : " + cust.Email;
            return dtocus;
        }
        #endregion CustomerConvertor
    }
}

The WCF Service code will look like as

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Channels;
using NHibernate;
using WCFNHibernateSilverLightSample.Web.DTOEntities;
using WCFNHibernateSilverLightSample.Web.DTOEntities.DTOConvertor;

namespace WCFNHibernateSilverLightSample.Web
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "GetDataService" in code, svc and config file together.
    public class GetDataService : IGetDataService
    {
        public IList<DTOCustomer> GetCustomer()
        {
            IList<Customer> list;
            IList<DTOCustomer> listDTO =  new List<DTOCustomer>();
            NHibernate.ISession session = NHibernateHelper.OpenSession();
            ICriteria query = session.CreateCriteria(typeof(Customer));
            list = query.List<Customer>();

            foreach(Customer c in list)
            {
                listDTO.Add(DTOConvertor.ConvertFromCustomerToDTOCustomer(c));
            }
            return listDTO;
        }
        public IList<DTOCustomerVersionWithAddress> GetCustomerWithAddress()
        {
            IList<Customer> list;
            IList<DTOCustomerVersionWithAddress> listDTO = new List<DTOCustomerVersionWithAddress>();
            NHibernate.ISession session = NHibernateHelper.OpenSession();
            ICriteria query = session.CreateCriteria(typeof(Customer));
            list = query.List<Customer>();

            foreach (Customer c in list)
            {
                listDTO.Add(DTOConvertor.ConvertFromCustomerToDTOCustomerVersionWithAddress(c));
            }
            return listDTO;
        }
    }
}

You can download sample here.
Rename the file as sample.zip and then extract.


Software Architecture – Design Problem – MS Visual Studio 2010 + .Net 4.0 + WCF + NHibernate + Silverlight

July 28, 2010

Environment: MS Visual Studio 2010 + .Net 4.0 + WCF + NHibernate + Silverlight

This post assumes that you have initial knowledge of WCF, NHibernate, Silverlight.

See the sample code for this solution working here.
Rename file as up.zip for extracting.

Sample Project:

Entities Relation / Tables relation is like:

Region >> Country >> City >> Area

So each region has many countries, Each country has many cities. Each City has many regions.
A typical Silverlight solution is created with 2 projects (One for silverlight(Client side project), other for ASP .Net Web project (server side ) having a WCF Service for data transfer from server side to client side.

Problem Definition:

Lets suppose you want to get list of City with lazy=”false” and fetch=”join”
for all entities So we will get following queries in SQL Profiler:

SELECT this_.CityID as CityID3_2_, this_.CountryID as CountryID3_2_, this_.CityCode as CityCode3_2_, this_.Description as Descript4_3_2_, this_.Active as Active3_2_, country2_.CountryID as CountryID1_0_, country2_.CountryCode as CountryC2_1_0_, country2_.Description as Descript3_1_0_, country2_.Active as Active1_0_, country2_.RegionId as RegionId1_0_, regions3_.RegionID as RegionID0_1_, regions3_.RegionCode as RegionCode0_1_, regions3_.Description as Descript3_0_1_, regions3_.Active as Active0_1_ FROM GeneralCityMaster this_ left outer join GeneralCountryMaster country2_ on this_.CountryID=country2_.CountryID left outer join GeneralRegionMaster regions3_ on country2_.RegionId=regions3_.RegionID

Again get list of City with lazy=”false” and fetch=”select”
for all entities So we will get following queries in SQL Profiler:

SELECT this_.CityID as CityID3_0_, this_.CountryID as CountryID3_0_, this_.CityCode as CityCode3_0_, this_.Description as Descript4_3_0_, this_.Active as Active3_0_ FROM GeneralCityMaster this_

For each country in list, there will be an select from country table as:

exec sp_executesql N'SELECT country0_.CountryID as CountryID1_0_, country0_.CountryCode as CountryC2_1_0_, country0_.Description as Descript3_1_0_, country0_.Active as Active1_0_, country0_.RegionId as RegionId1_0_ FROM GeneralCountryMaster country0_ WHERE country0_.CountryID=@p0',N'@p0 int',@p0=1

For each region in list, there will be an select from region table as:

exec sp_executesql N'SELECT regions0_.RegionID as RegionID0_0_, regions0_.RegionCode as RegionCode0_0_, regions0_.Description as Descript3_0_0_, regions0_.Active as Active0_0_ FROM GeneralRegionMaster regions0_ WHERE regions0_.RegionID=@p0',N'@p0 int',@p0=21

Two Problems:
There are 2 problems with above implementation.

Lazy load is false, so on server side that is ASP .Net / WCF Project, if we need some processing to be done, it is loading all data, no lazy initialization helps us.

Secondly, in both above cases data is joined from all the corresponding tables even if it is not required. Suppose we want to get data of cities only but unfortunately data of country and region is also fetched and transfer of such a heavy data across the WCF wire is very heavy activity.

If you will change lazy=”true” for entities, then WCF will pass following error.

{System.Net.WebException: The remote server returned an error: NotFound.
   at System.Net.Browser.BrowserHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
   at System.Net.Browser.BrowserHttpWebRequest.<>c__DisplayClass5.<EndGetResponse>b__4(Object sendState)
   at System.Net.Browser.AsyncHelper.<>c__DisplayClass2.<BeginOnUI>b__0(Object sendState)}

In order to see the real problem, configure WCF Log as explained
as explained at here

On looking into



Exeption will look like as:

There was an error while trying to serialize parameter http://tempuri.org/:GetCitiesResult. The InnerException message was 'Type 'CountryProxy' with data contract name 'CountryProxy:http://schemas.datacontract.org/2004/07/' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'.  Please see InnerException for more details.

Stack trace will look like as:

System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameterPart(XmlDictionaryWriter writer, PartInfo part, Object graph)
System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameter(XmlDictionaryWriter writer, PartInfo part, Object graph)
System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeBody(XmlDictionaryWriter writer, MessageVersion version, String action, MessageDescription messageDescription, Object returnValue, Object[] parameters, Boolean isRequest)
System.ServiceModel.Dispatcher.OperationFormatter.SerializeBodyContents(XmlDictionaryWriter writer, MessageVersion version, Object[] parameters, Object returnValue, Boolean isRequest)
System.ServiceModel.Dispatcher.OperationFormatter.OperationFormatterMessage.OperationFormatterBodyWriter.OnWriteBodyContents(XmlDictionaryWriter writer)
System.ServiceModel.Channels.BodyWriter.WriteBodyContents(XmlDictionaryWriter writer)
System.ServiceModel.Channels.BodyWriterMessage.OnBodyToString(XmlDictionaryWriter writer)
System.ServiceModel.Channels.Message.ToString(XmlDictionaryWriter writer)
System.ServiceModel.Diagnostics.MessageLogTraceRecord.WriteTo(XmlWriter writer)
System.ServiceModel.Diagnostics.MessageLogger.LogInternal(MessageLogTraceRecord record)
System.ServiceModel.Diagnostics.MessageLogger.LogMessageImpl(Message&amp; message, XmlReader reader, MessageLoggingSource source)
System.ServiceModel.Diagnostics.MessageLogger.LogMessage(Message&amp; message, XmlReader reader, MessageLoggingSource source)
System.ServiceModel.Dispatcher.DispatchOperationRuntime.SerializeOutputs(MessageRpc&amp; rpc)
System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc&amp; rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc&amp; rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc&amp; rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc&amp; rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc&amp; rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc&amp; rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc&amp; rpc)
System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump(RequestContext request, Boolean cleanThread, OperationContext currentOperationContext)
System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(RequestContext request, OperationContext currentOperationContext)
System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult result)
System.ServiceModel.Dispatcher.ChannelHandler.OnAsyncReceiveComplete(IAsyncResult result)
System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
System.Runtime.InputQueue`1.AsyncQueueReader.Set(Item item)
System.Runtime.InputQueue`1.EnqueueAndDispatch(Item item, Boolean canDispatchOnThisThread)
System.Runtime.InputQueue`1.EnqueueAndDispatch(T item, Action dequeuedCallback, Boolean canDispatchOnThisThread)
System.ServiceModel.Channels.SingletonChannelAcceptor`3.Enqueue(QueueItemType item, Action dequeuedCallback, Boolean canDispatchOnThisThread)
System.ServiceModel.Channels.HttpChannelListener.HttpContextReceived(HttpRequestContext context, Action callback)
System.ServiceModel.Activation.HostedHttpTransportManager.HttpContextReceived(HostedHttpRequestAsyncResult result)
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.HandleRequest()
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.BeginRequest()
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequest(Object state)
System.Runtime.IOThreadScheduler.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)
System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)

This exception reflects that when WCF serializer tries to load countries, it fails because of lazy loading being true as country will be a proxy object, so it will pass the exception.

Solution:
After reviewing the suggestions provided by Sowmy Srinivasan’s Blog at:
http://blogs.msdn.com/b/sowmy/archive/2006/03/26/561188.aspx

and discussion on Johan Danforth’s Blog at:
http://weblogs.asp.net/jdanforth/archive/2008/12/22/nhibernate-and-wcf-is-not-a-perfect-match.aspx

I have introduced 3 new classes as:

1. HibernateDataContractSurrogate which implements IDataContractSurrogate which replaces proxy object with forcefully created object by the DataContractSerializer of WCF during serialization.

MSDN Reference:
http://msdn.microsoft.com/en-us/library/ms574969.aspx

2. ReferencePreservingDataContractSerializerOperationBehavior
Which is derived from DataContractSerializerOperationBehavior will extend the functionality provided by DataContract behavior.

3. ReferencePreservingDataContractFormatAttribute which provide attribute that will apply the behavior created above with name
ReferencePreservingDataContractSerializerOperationBehavior

So in short we have modified the behavior of data contract by using IDataContractSurrogate to replace proxy object with forcefully created object.

After this above change of introducing 3 classes, old exception of countryproxy will disappear, but a new exception will be there as below.

There was an error while trying to serialize parameter http://tempuri.org/:GetCitiesResult. The InnerException message was 'Type 'WCFNHibernateSilverLightSample.Web.City' with data contract name 'City:http://schemas.datacontract.org/2004/07/WCFNHibernateSilverLightSample.Web' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'.  Please see InnerException for more details.

Trace as:

System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameterPart(XmlDictionaryWriter writer, PartInfo part, Object graph)
System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameter(XmlDictionaryWriter writer, PartInfo part, Object graph)
System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeBody(XmlDictionaryWriter writer, MessageVersion version, String action, MessageDescription messageDescription, Object returnValue, Object[] parameters, Boolean isRequest)
System.ServiceModel.Dispatcher.OperationFormatter.SerializeBodyContents(XmlDictionaryWriter writer, MessageVersion version, Object[] parameters, Object returnValue, Boolean isRequest)
System.ServiceModel.Dispatcher.OperationFormatter.OperationFormatterMessage.OperationFormatterBodyWriter.OnWriteBodyContents(XmlDictionaryWriter writer)
System.ServiceModel.Channels.BodyWriter.WriteBodyContents(XmlDictionaryWriter writer)
System.ServiceModel.Channels.BodyWriterMessage.OnBodyToString(XmlDictionaryWriter writer)
System.ServiceModel.Channels.Message.ToString(XmlDictionaryWriter writer)
System.ServiceModel.Diagnostics.MessageLogTraceRecord.WriteTo(XmlWriter writer)
System.ServiceModel.Diagnostics.MessageLogger.LogInternal(MessageLogTraceRecord record)
System.ServiceModel.Diagnostics.MessageLogger.LogMessageImpl(Message&amp; message, XmlReader reader, MessageLoggingSource source)
System.ServiceModel.Diagnostics.MessageLogger.LogMessage(Message&amp; message, XmlReader reader, MessageLoggingSource source)
System.ServiceModel.Dispatcher.DispatchOperationRuntime.SerializeOutputs(MessageRpc&amp; rpc)
System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc&amp; rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc&amp; rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc&amp; rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc&amp; rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc&amp; rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc&amp; rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc&amp; rpc)
System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump(RequestContext request, Boolean cleanThread, OperationContext currentOperationContext)
System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(RequestContext request, OperationContext currentOperationContext)
System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult result)
System.ServiceModel.Dispatcher.ChannelHandler.OnAsyncReceiveComplete(IAsyncResult result)
System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
System.Runtime.InputQueue`1.AsyncQueueReader.Set(Item item)
System.Runtime.InputQueue`1.EnqueueAndDispatch(Item item, Boolean canDispatchOnThisThread)
System.Runtime.InputQueue`1.EnqueueAndDispatch(T item, Action dequeuedCallback, Boolean canDispatchOnThisThread)
System.ServiceModel.Channels.SingletonChannelAcceptor`3.Enqueue(QueueItemType item, Action dequeuedCallback, Boolean canDispatchOnThisThread)
System.ServiceModel.Channels.HttpChannelListener.HttpContextReceived(HttpRequestContext context, Action callback)
System.ServiceModel.Activation.HostedHttpTransportManager.HttpContextReceived(HostedHttpRequestAsyncResult result)
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.HandleRequest()
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.BeginRequest()
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequest(Object state)
System.Runtime.IOThreadScheduler.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)
System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)

Solution for the above exception is provided at:
http://msdn.microsoft.com/en-us/library/system.servicemodel.serviceknowntypeattribute.aspx

Introduce ServiceKnownType attribute in service contract with a helper class,
So the Service will look like as:

// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IGetDataService" in both code and config file together.
    [ServiceContract]
    [ServiceKnownType("GetKnownTypes", typeof(Helper))]
    public interface IGetDataService
    {

        [OperationContract]        
        [ReferencePreservingDataContractFormat]
        IList<City> GetCities();
    }



// This class has the method named GetKnownTypes that returns a generic IEnumerable.
    static class Helper
    {
        public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider provider)
        {
            System.Collections.Generic.List<System.Type> knownTypes =
                new System.Collections.Generic.List<System.Type>();
            // Add any types to include here.
            knownTypes.Add(typeof(City));
            knownTypes.Add(typeof(Country));
            knownTypes.Add(typeof(Regions));
            knownTypes.Add(typeof(AreaMaster));
            
            return knownTypes;
        }
    }

So now the first problem has been solved. So now in business classes we can use objects with lazy loading working, only required object will be initialized. We have lazy loading true in OR Mapping, so on Server side “WCFNHibernateSilverLightSample.Web” project will access the object model with fully operational benefits of lazy loading.

See the sample code for this solution working here.

But second problem still exists. To solve the second problem, DTO (Data Transfer Objects) are used. DTO object are simple entity objects have the only those properties that needs to be transferred via WCF wire, So OR Mapping Nhibernate object will be different from DTO objects. Once the data is fetched in OR Mapping Nhibernate object, a transformation is done to DTO object and light weight DTO objects are passed with WCF to client end silverlight project.

I will do one more post to demonstrate this second problem in next post.

Both problems must be solved in a Good designed WCF/Sliverlight/Nhibernate project.

Happy Coding.