WCF bindings provide the MaxReceivedMessageSize property, which lets you block any incoming messages on the client side over a given size (defaulting to 64Kb). If you’re using message-based itinerary processing with ESB Guidance, when a WCF service returns a message larger than this default, you’ll get a System.ServiceModel.QuotaExceededException and the response message will be suspended:
System.ServiceModel.CommunicationException: The maximum message size quota for incoming messages (65536) has been exceeded. To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element. —> System.ServiceModel.QuotaExceededException: The maximum message size quota for incoming messages (65536) has been exceeded. To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element.
Setting the MaxReceivedMessageSize property is straightforward in a configured WCF port, but in ESB Guidance the port is configured dynamically and there’s no straightforward way to interrupt it and add your own WCF bindings. To give us access to the message and the port, we replaced the “DynamicSendResponse” port used in the GlobalBank.ESB sample with a simple orchestration.
The orchestration has a direct-bound receive port filtering on the usual properties:
(Microsoft.Practices.ESB.Itinerary.Schemas.ServiceName == “DynamicResolutionSolicitResp”) &&
(Microsoft.Practices.ESB.Itinerary.Schemas.ServiceState == “Pending”) &&
(Microsoft.Practices.ESB.Itinerary.Schemas.ServiceType == “Messaging”)
– it then builds the outgoing message for the service, and configures the dynamic send/receive port. At this point the message has all the properties you need configured by ESB (via the resolver pipeline component in the previous itinerary steps), so you can extract them to configure the port, and add any WCF binding configuration you need.
We store the configuration in the Enterprise Single Sign-On application config store using SSO Config Tool, so the expression to build the outgoing message and increase the received message size looks like this –
//setup port from context properties:
sptServiceProvider(Microsoft.XLANGs.BaseTypes.Address) = ServiceProviderRequest(BTS.OutboundTransportLocation);
sptServiceProvider(Microsoft.XLANGs.BaseTypes.TransportType) = ServiceProviderRequest(BTS.OutboundTransportType);
//set message size from config:
maxReceivedMessageSize = x.y.z.Configuration.X_Y_Z_Config.WCFMaxReceivedMessageSize;
ServiceProviderRequest(WCF.MaxReceivedMessageSize) = maxReceivedMessageSize;
Microsoft.Practices.ESB.Adapter.AdapterMgr.SetMsgProperty(ServiceProviderRequest, typeof(WCF.MaxReceivedMessageSize), maxReceivedMessageSize);
//set timeout from config:
sendTimeout = x.y.z.Configuration.X_Y_Z_Config.WCFSendTimeout;
ServiceProviderRequest(WCF.SendTimeout) = sendTimeout;
Note that the WCF config is set on the message, not on the port. We’re also setting timeout values here. When you’re dealing with large messages, you may get operation timeouts as the default binding config from BizTalk is set to a pessimistic 1 minute. Value WCF.SendTimeout specifies how long the BizTalk client waits for a response, and WCF.ReceiveTimeout how long the BizTalk client allows for the reception of a request. If your WCF service is hosted in IIS and is long-running, you may also have an issue with IIS controlling execution times. See: Why changing SendTimeout does not help for hosted WCF services.