|
WCF is ingericht in het versturen en ontvangen van berichten via verschillende soorten bindingen. De vraag- en antwoordberichten kunnen hierbij zelfs vele megabytes groot zijn. De maximale grootte wordt voornamelijk bepaald door het type binding, zo heeft MSMQ een limiet van vier megabytes. Maar standaard is de grootte veel beperkter ingesteld. 1. Het was de grootte van het aanvraagbericht welke problemen gaf, niet het antwoord 2. We gebruiken wsHTTP |
|
We wilden namelijk een grote lijst met ruwe data laten verwerken. Dit gebeurt stateless, de aanvraag opdelen in kleine stukken is geen optie. We kregen namelijk al problemen bij het versturen vanaf iets meer dan acht KB.
System.ServiceModel.FaultException`1 was unhandled
Message="The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:composite. The InnerException message was 'There was an error deserializing the object of type CompositeType. The maximum string content length quota (8192) has been exceeded while reading XML data. This quota may be increased by changing the MaxStringContentLength property on the XmlDictionaryReaderQuotas object used when creating the XML reader. Line 1, position 9020.'. Please see InnerException for more details."
Bij meer dan negentig KB kregen we de volgende melding:
System.ServiceModel.ProtocolException was unhandled
Message="The remote server returned an unexpected response: (400) Bad Request."
Beide meldingen komen voort uit de standaard instellingen van de binding. Maar wat zijn die instellingen dan? Waar kan je die vinden?
Ik heb hiervoor een testsituatie gebouwd: een WCF webservice host wordt aangeroepen door een console applicatie. De host ondersteunt één methode welke een string accepteert en een string retourneert. De methode geeft een string terug met de inhoud van de tien keer de parameter achter elkaar. Als je de cliëntreferentie laat genereren, kijk dan eens in de app.config van de cliënt. Daar is een complete bindingconfiguratie aan toegevoegd:
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService" ...
</binding>
</wsHttpBinding>
</bindings>
Deze bindingconfiguratie wordt aan het ABC (adres, binding en contract) toegevoegd via een extra attribuut:
<endpoint address=http://localhost:1234/WCFService/Service.svc binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService" contract="ServiceReference.IService" name="WSHttpBinding_IService">
Kijk nu eens naar de host web.config. Deze is veel eenvoudiger:
<endpoint address="" binding="wsHttpBinding" contract="IService" >
Op de host is de binding blijkbaar al standaard geconfigureerd en deze settings zijn in de cliënt netjes herhaald en uitgeschreven. Let wel: deze instellingen moeten wel aan beide kanten gelijk aan elkaar gemaakt worden.
Tussen de binding-instellingen staat ook de al eerder genoemde instelling maxStringContentLength. Als je deze in de app.config aanpast zal er niet veel gebeuren... Zoals hiervoor al gezegd, cliënt en host moeten op elkaar aansluiten. Het is dus zaak de aangepaste binding configuratie ook de host door te voeren. Kopieer dus de <bindings> instellingen uit de app.config gewoon door naar de web.config. Vergeet niet in het EndPoint element het attribuut bindingConfiguration="WSHttpBinding_IService" op te nemen.
Dit helpt in eerste instantie wel. Maar met wat grotere berichten krijgen we al snel de melding:
System.ServiceModel.CommunicationException was unhandled
Message="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."
Door dus ook de MaxReceivedMessageSize aan beide zijden te vergroten wordt het mogelijk om grote berichten te versturen, en ontvangen. Bij veel voorbeelden op het internet worden gewoon alle instellingen verminkt, ik heb hier willen aantonen dat met goed lezen en enkele eenvoudige aanpassingen de problemen al opgelost kunnen worden.
Het is hierbij aardig om te weten dat ‘recieve' altijd vanuit de context van de cliënt of de host geldt. De MaxReceivedMessageSize in de app.config geldt bij de cliënt dus voor de berichten vanaf de host richting de cliënt, nav. een aanvraag.
Kijk nog eens naar de meldingen bovenaan in deze blog. De eerste FaultException werd gegooid omdat de cliënt een te lang antwoord moest ontvangen (tien maal de aangeboden tekst van acht KB). De http Error 400 Bad Request was vrijwel zeker dezelfde fout aan de host kant door de verminkte request (te lange parameter). Helaas wordt dit als een Bad Request teruggegooid, de host neemt het bericht gewoon niet in ontvangst zodra er teveel data ontvangen wordt.
Kijk voor meer informatie over de verschillende binding configuraties hier zoals die van de wsHttp.
Share this | 1281 keer bekeken | 1 reactie






Paul Berndsen reageert, op March 2, 2009 om 09:41 (GMT +01:00):
Dank je Sander. Ik zat steeds aan de client kant naar de oplossing voor het probleem te zoeken, terwijl het probleem dus blijkbaar aan de host kant zat.Problem solved.