Bug 15153

Summary: System.ServiceModel.NetTcpBinding properties are not pre-initialized while they are in .Net causing interoperability problems
Product: [Mono] Class Libraries Reporter: Eddy Hahn <eddyhahn>
Component: WCF assembliesAssignee: Bugzilla <bugzilla>
Status: RESOLVED FIXED    
Severity: normal CC: bwana.marko, ludovic, mono-bugs+mono
Priority: ---    
Version: unspecified   
Target Milestone: Untriaged   
Hardware: Other   
OS: All   
Tags: Is this bug a regression?: ---
Last known good build:

Description Eddy Hahn 2013-10-02 19:20:15 UTC
Description of Problem:
Properties of System.ServiceModel.NetTcpBinding should be pre-created just like .Net.  Specifically ReaderQuotas and ReliableSession properties should have the objects precreated and initialized.

Steps to reproduce the problem:
1. Create NetTcpBinding and try to set a property of ReaderQuotas or ReliableSession.  Both will throw a NullObject exception.  In .Net (Microsoft) when a NetTCPBiniding is created thoese two properties are point to a pre-created instance.
2.
NetTcpBinding binding = new NetTcpBinding();

binding.ReaderQuotas.MaxDepth = 64;   //will cause an error in Mono ReaderQuotas are not initialized with an object.  .Net will work
binding.ReliableSession.Enabled = false;   //same here. But worst because ReliableSession is read only so there is no way to fix it by creating the object for ReliableSession


Actual Results:
Assembly moved from Windows (it works on Windows) will break because un-initialized properties in Mono

Expected Results:
These properties are pre-initialized just like in .Net and assembly work when copied from Windows.

How often does this happen? 
Always

Additional Information:
Comment 1 Mark Mikofski 2015-06-16 14:20:48 UTC
This issue is caused by not initializing the `reader_quotas` member in `TcpNetBinding` class of `System.ServiceModel` here:
https://github.com/mono/mono/blob/master/mcs/class/System.ServiceModel/System.ServiceModel/NetTcpBinding.cs#L46

Patch it from the `HttpBindingBase` to initialize `reader_quotas` to an `XmlDictionaryReaderQuotas` object from here:
https://github.com/mono/mono/blob/master/mcs/class/System.ServiceModel/System.ServiceModel/HttpBindingBase.cs#L52

Here is a patch:

--- original/NetTcpBinding.cs
+++ patched/NetTcpBinding.cs
@@ -43,7 +43,8 @@
         int max_conn;
         OptionalReliableSession reliable_session;
         NetTcpSecurity security;
-        XmlDictionaryReaderQuotas reader_quotas;
+XmlDictionaryReaderQuotas reader_quotas
+            = new XmlDictionaryReaderQuotas();
         bool transaction_flow;
         TransactionProtocol transaction_protocol;
         TcpTransportBindingElement transport;

A workaround is to initialize the `ReaderQuotas` manually after initializing the binding:

    // new net.tcp binding
    NetTcpBinding binding = new NetTcpBinding(SecurityMode.None);
    // workaround for uninitialized ReaderQuotas member
    binding.ReaderQuotas = new XmlDictionaryReaderQuotas();
    // set proporties, doesn't raise NullReferenceException
    binding.ReaderQuotas.MaxStringContentLength = 8192;

Thank you Xamarin Team for this valuable contribution!
Comment 2 Mark Mikofski 2015-06-16 14:50:01 UTC
I have submitted my patch on github as PR1879 here:
https://github.com/mono/mono/pull/1879


oops there was a typo in the last comment, spaces were missing from the patch

--- original/NetTcpBinding.cs
+++ patched/NetTcpBinding.cs
@@ -43,7 +43,8 @@
         int max_conn;
         OptionalReliableSession reliable_session;
         NetTcpSecurity security;
-        XmlDictionaryReaderQuotas reader_quotas;
+        XmlDictionaryReaderQuotas reader_quotas
+            = new XmlDictionaryReaderQuotas();
         bool transaction_flow;
         TransactionProtocol transaction_protocol;
         TcpTransportBindingElement transport;


sorry. The PR does not have the typo. Again, thanks so much to Xamarin for Mono, and thanks for considering my patch.

Until the patch makes it to release, others can use this workaround also mentioned my last comment:

    // new net.tcp binding
    NetTcpBinding binding = new NetTcpBinding(SecurityMode.None);
    // workaround for uninitialized ReaderQuotas member
    binding.ReaderQuotas = new XmlDictionaryReaderQuotas();
    // set proporties, doesn't raise NullReferenceException
    binding.ReaderQuotas.MaxStringContentLength = 8192;
Comment 3 Ludovic Henry 2015-12-17 11:33:56 UTC
Fixed on master with https://github.com/mono/mono/pull/2353