Buffer Size error when retrieving Metadata - How to increase size?
I am trying to retrieve the MetaData from the WCF Service using the following method.
// Create a MetadataExchangeClient for retrieving metadata. EndpointAddress mexAddress = new EndpointAddress( uri ); MetadataExchangeClient mexClient = new MetadataExchangeClient( mexAddress ); // Retrieve the metadata for all endpoints using metadata exchange protocol (mex). MetadataSet metadataSet = mexClient.GetMetadata();How do I increase the buffer size?
Thanks,
Dave An exception is being generatedMetadata contains a reference that cannot be resolved: 'http://localhost/EventTest/ServiceReport.svc/mex/'.
at System.ServiceModel.Description.MetadataExchangeClient.MetadataRetriever.Retrieve(TimeoutHelper timeoutHelper)
at System.ServiceModel.Description.MetadataExchangeClient.ResolveNext(ResolveCallState resolveCallState)
at System.ServiceModel.Description.MetadataExchangeClient.GetMetadata(MetadataRetriever retriever)
at System.ServiceModel.Description.MetadataExchangeClient.GetMetadata(EndpointAddress address)
at System.ServiceModel.Description.MetadataExchangeClient.GetMetadata()
at Utiltiies.WCF.Services.MetaData.Retrieve(String uri) in C:\temp\XmlGenerator\ServiceUtiltiies\MetaData.cs:line 61Inner Exception
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.
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.
Server stack trace:
at System.ServiceModel.Channels.HttpInput.ThrowMaxReceivedMessageSizeExceeded()
at System.ServiceModel.Channels.HttpInput.GetMessageBuffer()
at System.ServiceModel.Channels.HttpInput.ReadBufferedMessage(Stream inputStream)
at System.ServiceModel.Channels.HttpInput.ParseIncomingMessage(Exception& requestException)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at System.ServiceModel.Description.IMetadataExchange.Get(Message request)
at System.ServiceModel.Description.MetadataExchangeClient.MetadataReferenceRetriever.DownloadMetadata(TimeoutHelper timeoutHelper)
at System.ServiceModel.Description.MetadataExchangeClient.MetadataRetriever.Retrieve(TimeoutHelper timeoutHelper)
Answers
The <mexHttpBinding> configuration section doesn't have any properties. In fact, it is just a wrapper for WSHttpBinding internally, with SecurityMode.None.
The following code will work:
System.ServiceModel.WSHttpBinding binding = new System.ServiceModel.WSHttpBinding(System.ServiceModel.SecurityMode.None);
binding.MaxReceivedMessageSize = 50000000;
System.ServiceModel.Description.
MetadataExchangeClient mexClient = new System.ServiceModel.Description.MetadataExchangeClient(binding);System.ServiceModel.Description.
MetadataSet metadataSet = mexClient.GetMetadata(new System.ServiceModel.EndpointAddress("http://localhost:8000/HelloIndigo/mex"));It turns out you can set the endpoint when you call GetMetadata() so my earlier observation that the construction process was limiting, it something we can overcome by intitializing with the binding, and supplying endpoint during the call. Supply your own endpoint of course :)
I just posted two samples for this, that illustrate service configuration for larger mex binding, with a client that is config-based, and another that is code-based.
http://www.dasblonde.net/downloads/wcf/CustomMexBinding.zip
http://www.dasblonde.net/downloads/wcf/CustomMexBindingCode.zip
All Replies
The way you are initializing the MetadataExchangeClient type it is expecting to find an IMetadataExchange endpoint configuration in the client config file. If you don't provide one, it creates one using defaults for wsHttpBinding for you. If you do provide on, you can customize the binding config by supply this endpoint:
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" bindingConfiguration="mexHttp" address="mex" />
And this binding implementation with a larger received message size:
<wsHttpBinding>
<binding name="wsHttp" maxReceivedMessageSize ="5000000">
</binding>
</wsHttpBinding>
And, by the way, the service will also have the same problem, so you have to do the same on that end.
If you want to initialize the MetadataExchangClient binding using code, you could use the constructor that takes a binding parameter. The problem with this is that then you can't set the endpoint. So, it appears this class is poorly designed so that you can't do a fully functional customization of the endpoint and channel factory at runtime, due to private members. I hope that is fixed!!!!
I tried as you sugessted using this as the config file
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <bindings> <wsHttpBinding> <binding name="wsHttp" maxReceivedMessageSize="5000000" /> </wsHttpBinding> </bindings> <client> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" bindingConfiguration="mexHttp" /> </client> </system.serviceModel> </configuration>This however, throws an exception of
There is no binding named 'mexHttp' at system.serviceModel/bindings/mexHttpBinding. Invalid value for bindingConfiguration.
If I add a new binding section
<mexHttpBinding> <binding name="mexHttp" /> </mexHttpBinding> and re-run the code I get The given URI must be absolute. Parameter name: uri I then name my endpoint <endpoint name="myendpoint" address="mex" binding="mexHttpBinding" contract="IMetadataExchange" bindingConfiguration="mexHttp" /> I get the same error, I had beforeThe maximum message size quota for incoming messages (65536) has been exceeded. To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element.
If I add the message size
<mexHttpBinding> <binding name="mexHttp" maxReceivedMessageSize="5000000" /> </mexHttpBinding> I getUnrecognized attribute 'maxReceivedMessageSize'. Note that attribute names are case-sensitive.
Any additional thoughts are appreciated.
Dave
The <mexHttpBinding> configuration section doesn't have any properties. In fact, it is just a wrapper for WSHttpBinding internally, with SecurityMode.None.
The following code will work:
System.ServiceModel.WSHttpBinding binding = new System.ServiceModel.WSHttpBinding(System.ServiceModel.SecurityMode.None);
binding.MaxReceivedMessageSize = 50000000;
System.ServiceModel.Description.
MetadataExchangeClient mexClient = new System.ServiceModel.Description.MetadataExchangeClient(binding);System.ServiceModel.Description.
MetadataSet metadataSet = mexClient.GetMetadata(new System.ServiceModel.EndpointAddress("http://localhost:8000/HelloIndigo/mex"));It turns out you can set the endpoint when you call GetMetadata() so my earlier observation that the construction process was limiting, it something we can overcome by intitializing with the binding, and supplying endpoint during the call. Supply your own endpoint of course :)
I just posted two samples for this, that illustrate service configuration for larger mex binding, with a client that is config-based, and another that is code-based.
http://www.dasblonde.net/downloads/wcf/CustomMexBinding.zip
http://www.dasblonde.net/downloads/wcf/CustomMexBindingCode.zip
Setting my config to
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <bindings> <wsHttpBinding> <binding name="mexBinding" maxReceivedMessageSize="5000000"> <security mode="None"/> </binding> </wsHttpBinding> </bindings> <client> <endpoint binding="wsHttpBinding" contract="IMetadataExchange" bindingConfiguration="mexBinding" /> </client> </system.serviceModel> </configuration>fixed the issue. I would like to note that the <security mode="None"/> node MUST be included for it to work.
Thanks for your assistance.
Dave
hi
i just had a query. is it possible that use some other metadata which is not wsdl. how can i do that programatically using metadataset class. how can i import metadata that is not wsdl.
- I am using SIF to access WCF .It worked for me. Thanaks dude!!!!
Below is what my web.config file looks like. I'm not sure how to edit/interject what is being recommended. Can someone please help me? Thanks!
<?
xml version="1.0" encoding="utf-8" ?><
configuration><
system.serviceModel><
services><!--
Address --><
service name="FRC.COW.Feedyard.Service.FRC.COW.Feedyard.Service.Address" behaviorConfiguration="AddressBehavior"><
endpoint address="" binding="basicHttpBinding" contract="FRC.COW.Feedyard.Service.FRC.COW.Feedyard.Service.IAddress"/><
endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" /></
service><!--
Animal --><
service name="FRC.COW.Feedyard.Service.FRC.COW.Feedyard.Service.Animal" behaviorConfiguration="AnimalBehavior"><
endpoint address="" binding="basicHttpBinding" contract="FRC.COW.Feedyard.Service.FRC.COW.Feedyard.Service.IAnimal"/><
endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" /></
service><!--
Arrival --><
service name="FRC.COW.Feedyard.Service.FRC.COW.Feedyard.Service.Arrival" behaviorConfiguration="ArrivalBehavior"><
endpoint address="" binding="basicHttpBinding" contract="FRC.COW.Feedyard.Service.FRC.COW.Feedyard.Service.IArrival"/><
endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" /></
service></
services><
behaviors><
serviceBehaviors><!--
Address --><
behavior name="AddressBehavior" ><
serviceMetadata httpGetEnabled="true" /><
serviceDebug includeExceptionDetailInFaults="true" /></
behavior><!--
Arrival --><
behavior name="ArrivalBehavior" ><
serviceMetadata httpGetEnabled="true" /><
serviceDebug includeExceptionDetailInFaults="true" /></
behavior><!--
Animal --><
behavior name="AnimalBehavior" ><
serviceMetadata httpGetEnabled="true" /><
serviceDebug includeExceptionDetailInFaults="true" /></
behavior></
serviceBehaviors></
behaviors></
system.serviceModel></
configuration>See the samples I posted here for creating a custom mexHttpBinding using wsHttpBinding instead.
http://www.dasblonde.net/downloads/wcf/CustomMexBinding.zip
http://www.dasblonde.net/downloads/wcf/CustomMexBindingCode.zip
Hi there.
I am usng VS 2008 and Created a Simple Service (Not A WCF Service). I am getting the Same Exception when I call a method in My web service.
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.
The solution given here is for WCF Service. I have a simple service with the framework 3.5
Any thoughts? Am I missing something?
thanks
Amol wankhede
I attempted to rewrite the code below to use new MetadataExchangeClient(binding);
But it gave an error about not passing the Username. I am using SmartChannelFactory with Username authentication. In my code Username and Password are not passed in until much later. The code below is in the Initializion process.
It gives an error about MaxReceivedMessageSize is over 65536.
How do I rewrite the code below to set the MaxReceivedMessageSize to 50000000?
try
{
//Check if the service is started @ the baseAddress providedSystem.Net.
WebRequest.Create(serviceMexAddress).GetResponse(); //Import metadata MetadataExchangeClient __mexClient = new MetadataExchangeClient(serviceMexAddress, MetadataExchangeClientMode.HttpGet); MetadataSet __metadataSet = __mexClient.GetMetadata(); WsdlImporter __importer = new WsdlImporter(__metadataSet); //Add custom wsdl importer to read wsdl timestamp info__importer.WsdlImportExtensions.Add(
new WsdlContractTimestampImporter()); Collection<ContractDescription> __contractDescritions = __importer.ImportAllContracts(); //Resolve wsdl into ServiceEndpointCollection__serviceEndPoints =
MetadataResolver.Resolve(__contractDescritions, serviceMexAddress, MetadataExchangeClientMode.HttpGet, __mexClient);}
catch(InvalidOperationException ioe){
//Service is offline or cannot be reached. throw new CommunicationException(String.Format("There is no Endpoint listening at {0}. Check that the service is running.", serviceMexAddress));}
I figured out how to handle my problem and it works now.
MetadataExchangeClient
__mexClient = null; MetadataSet __metadataSet = null; if (_binding != null){
new MetadataExchangeClient(_binding);__mexClient =
__metadataSet = __mexClient.GetMetadata(serviceMexAddress,
MetadataExchangeClientMode.HttpGet);}
else{
//Import metadata__mexClient =
new MetadataExchangeClient(serviceMexAddress, MetadataExchangeClientMode.HttpGet);__metadataSet = __mexClient.GetMetadata();
}
WsdlImporter __importer = new WsdlImporter(__metadataSet);


