Derik Whittaker

Syndication

News


Setting MaxItemsInObjectGraph for WCF, there has to be a better way

Toady we ran into an issue where the serialization graph of our objects exceeded the default max limits (yea I know, I need to resolve this as my root issue, but one step at a time).  When I used the WcfTestClient to test for a working solution for my problem I simply had to make a few config changes.  In fact I only needed to add the following to my config

<behaviors>
    <endpointBehaviors>
        <behavior name="Behaviors.EndpointBehavior">
            <dataContractSerializer maxItemsInObjectGraph="2147483647" />
        </behavior>
    </endpointBehaviors>
</behaviors>

AND

<client>
    <endpoint address=http://localhost:9997/Services/MyService
        behaviorConfiguration="Behaviors.EndpointBehavior"
        binding="wsHttpBinding" bindingConfiguration="WSHTTPBinding.Configuration.Client"
        contract="IAppointments" name="Client.EndpointConfiguration" />
</client>

However, because we are not using straight config to drive our WCF this solution was not something we could use.  Long story short we basically spin up our endpoints on our client dynamically.  Because of this we need to set the MaxItemsInObjectGraph property by hand.  I had expected i could create an instance of my endpoint Behavior I had created above (Client.EndpointConfiguration) and push this behavior to my at the service level and be done with it.  But from all my googling all I could find online has you setting this property on each operation on the contract. 

foreach ( var operation in channelFactory.Endpoint.Contract.Operations )
{
    var behavior = operation.Behaviors.Find() as DataContractSerializerOperationBehavior;
    if ( behavior != null )
    {
        behavior.MaxItemsInObjectGraph = 2147483647;    
    }
}

Now, I am reaching out to the blogosphere to ask, is there a better way to do this?

Till next time,


Posted 05-04-2010 1:06 PM by Derik Whittaker
Filed under: ,

[Advertisement]

Comments

David wrote re: Setting MaxItemsInObjectGraph for WCF, there has to be a better way
on 05-04-2010 4:03 PM

You can cut a few lines of code with LINQ and use a constant, yeah not much better I know.

var operations = _client.Endpoint.Contract.Operations;

foreach (var operation in operations)

{

operation.Behaviors.Find<DataContractSerializerOperationBehavior>().MaxItemsInObjectGraph = MAX_ITEMS_IN_OBJECT_GRAPH;

}

Krzysztof Koźmic wrote re: Setting MaxItemsInObjectGraph for WCF, there has to be a better way
on 05-05-2010 3:05 AM

Welcome to my world.

Unfortunately I don't think there's any simpler way to do it OOTB

Andy Pook wrote re: Setting MaxItemsInObjectGraph for WCF, there has to be a better way
on 05-05-2010 4:00 AM

Extension methods are your friend

Derik Whittaker wrote re: Setting MaxItemsInObjectGraph for WCF, there has to be a better way
on 05-05-2010 5:23 AM

@Andy,

Extension methods do not remove the pain, they just move it.

Leon Breedt wrote re: Setting MaxItemsInObjectGraph for WCF, there has to be a better way
on 05-05-2010 6:54 AM

On a late-night call to a customer, we found it possible to override using machine.config (potentially app.exe.config as well, I do not recall, it was a "get-it-working-now" deal).

But our final solution was to do the override in code like you posted.

Leon Breedt wrote re: Setting MaxItemsInObjectGraph for WCF, there has to be a better way
on 05-05-2010 7:02 AM

Found the support ticket.

Yep, machine.config, ugh. But potentially it may be possible to modify this at a less invasive level, I don't recall if this was possible in an application configuration file, and don't have a machine at hand to test it right now.

But the config-only workaround involved modifying <commonBehaviors> in <system.serviceModel> to look as follows:

<commonBehaviors>

   <endpointBehaviors>

       <dataContractSerializer maxItemsInObjectGraph="2147483647" />

   </endpointBehaviors>

   <serviceBehaviors>

       <dataContractSerializer maxItemsInObjectGraph="2147483647" />

   </serviceBehaviors>

</commonBehaviors>

You may see some lines in there about a Visual Studio ServiceModelSink, which you probably want to preserve, but they should not be present on a machine without VS installed.

HTH

Craig Neuwirt wrote re: Setting MaxItemsInObjectGraph for WCF, there has to be a better way
on 05-05-2010 8:01 AM

I wrote some contract/operation behaviors that enabled be to control preserving of object references.  It also allows you to set MaxItemsInObjectGraph.  It can be applied to contacts/methods or added as a general behavior.  If you want it send me and emai @

cneuwirt@gmail.com

Derik Whittaker wrote re: Setting MaxItemsInObjectGraph for WCF, there has to be a better way
on 05-05-2010 8:24 AM

@Leon,

Thanks, but sadly as we are a off the shelf install (ok, mostly) we really try not to make these type of system changes if we can help it.

Scott Seely wrote re: Setting MaxItemsInObjectGraph for WCF, there has to be a better way
on 05-05-2010 10:14 AM

Derik,

You can also create a custom ServiceHost and have it populate the Endpoint behavior on ServiceHost.Open(). I can blog this soon if you need it.

Derik Whittaker wrote re: Setting MaxItemsInObjectGraph for WCF, there has to be a better way
on 05-05-2010 10:27 AM

@Scott,

I think that ServiceHost is on the hosting side, not the client side right?  If this is the case the config on the server side worked.  But I need this on the client side in order to receive/send from the client back.

If i am wrong please ping me off line.

Igor Brejc wrote re: Setting MaxItemsInObjectGraph for WCF, there has to be a better way
on 05-06-2010 7:09 AM

I had a very similar issue yesterday: setting the MaxStringContentLength to a higher value to allow longer string content to be passed to our REST service. Since we've using a custom WCF REST + Castle solution, I've had to adjust this setting by overriding IEndpointBehavior.AddBindingParameters() method, like:

       public override void AddBindingParameters(

           ServiceEndpoint endpoint,

           System.ServiceModel.Channels.BindingParameterCollection bindingParameters)

       {

           base.AddBindingParameters(endpoint, bindingParameters);

           SetBindingQuotas((WebHttpBinding)endpoint.Binding);

       }

       private void SetBindingQuotas(WebHttpBinding binding)

       {

           binding.ReaderQuotas.MaxStringContentLength = maxStringContentLength;            

       }

Ugly, but it works. BTW I consider WCF to be an ugly technology in general, so I kind of get used to such tweaks.

Scott Seely wrote Custom ChannelFactory Creation
on 05-07-2010 6:07 PM

Just the other day, Derik Whitaker ran into some issues setting up his ChannelFactory to handle large

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)