Sunday, January 2, 2011

Change MaxItemsInObjectGraph value on server and client side

When i was working with WCF + XPO i faced with the following problem.

CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '20.20:29:58.9889422'.

It was caused by large amount of data retrieved from the server which MaxItemsInObjectGraph configuration value set to default(65535). I googled so much and finally found the solution for this. By changing MaxItemsInObjectGraph to enough value on server and client side, it was solved.

Server side:
SqlConnection conn = new SqlConnection("Initial Catalog=flight; Data Source=NEU\\SQLEXPRESS; Integrated Security=SSPI;Persist Security Info=False");

IDataStore sourceDataStore = XpoDefault.GetConnectionProvider(conn,AutoCreateOption.DatabaseAndSchema);

DataStoreServerProxy publicationObject = new DataStoreServerProxy(sourceDataStore);

Uri baseAddress = new Uri("net.tcp://0.0.0.0:1234/");
serviceHost = new ServiceHost(publicationObject, baseAddress);
NetTcpBinding binding = new NetTcpBinding(SecurityMode.None);
binding.SendTimeout = new TimeSpan(500, 30, 0);
binding.ReceiveTimeout = new TimeSpan(500, 30, 0);
binding.OpenTimeout = new TimeSpan(500, 30, 0);
binding.CloseTimeout = new TimeSpan(500, 30, 0);
binding.MaxReceivedMessageSize = 2147483647;

serviceHost.AddServiceEndpoint(typeof(IDataStoreContract), binding, "XPOService");

serviceHost.Open();
foreach (OperationDescription operation in serviceHost.Description.Endpoints[0].Contract.Operations)
{
var behavior = operation.Behaviors.Find();
if (behavior != null)
behavior.MaxItemsInObjectGraph = 2147483647;
}


Client side:

NetTcpBinding binding = new NetTcpBinding(SecurityMode.None);

binding.MaxReceivedMessageSize = 2147483647;
binding.SendTimeout = new TimeSpan(500, 30, 0);
binding.ReceiveTimeout = new TimeSpan(500, 30, 0);
binding.OpenTimeout = new TimeSpan(500, 30, 0);
binding.CloseTimeout = new TimeSpan(500, 30, 0);


ChannelFactory factory = new ChannelFactory(binding, "net.tcp://localhost:1234/XPOService");
foreach (OperationDescription operation in factory.Endpoint.Contract.Operations)
{
var behavior = operation.Behaviors.Find();
if (behavior != null)
behavior.MaxItemsInObjectGraph = 2147483647;
}


DataStoreClientProxy remoteDataStore = new DataStoreClientProxy(factory.CreateChannel());

// Initialize XPO to use that reference
XpoDefault.DataLayer = new SimpleDataLayer(remoteDataStore);
XPClassInfo[] ClassInfos = { Session.DefaultSession.GetClassInfo(typeof(City)), Session.DefaultSession.GetClassInfo(typeof(CityArea)) };
XpoDefault.DataLayer.UpdateSchema(false, ClassInfos);