8

We have a setup that used to work and has stopped sometime over the past few months. We use a custom dead-letter queue that is specified in config but basically gets set like this::

MsmqIntegrationBinding msmq = new MsmqIntegrationBinding(
    // Defaults to WindowsDomain.  We want all messages to be authenticated.
    MsmqIntegrationSecurityMode.Transport);

msmq.DeadLetterQueue = DeadLetterQueue.Custom;
msmq.CustomDeadLetterQueue = new Uri("net.msmq://localhost/private/BulkUpdatesDeadLetter");

We've started getting this error, which seems to be pretty clear:

System.InvalidOperationException: A mismatch occurred between the binding and the MSMQ configuration. Messages cannot be sent. The custom dead letter queue specified in the binding must be a transactional queue. Ensure that the custom dead letter queue address is correct and the queue is a transactional queue.

We've verified both that we are pointing to the correct queue in the config and that the queue is transactional. Are there any other issues that might cause this exception to be thrown, or are we just missing something in the obvious?

Update: Had our web ops team delete and recreate the queues and still receiving the error.

abatishchev
  • 98,240
  • 88
  • 296
  • 433
zimdanen
  • 5,508
  • 7
  • 44
  • 89
  • Can you call `MQGetQueueProperties` directly with success? (see [this](http://referencesource.microsoft.com/#System.ServiceModel/System/ServiceModel/Channels/UnsafeNativeMethods.cs,d7405f40d25f6d42,references) and TryGetIsTransactional [here](http://referencesource.microsoft.com/#System.ServiceModel/System/ServiceModel/Channels/MsmqQueue.cs,f4a417a70378ae30)). – 500 - Internal Server Error Jul 14 '15 at 18:35
  • @500-InternalServerError: I'm assuming that's from the COM component? Do you have instructions on how to add that, because I've been trying today and can't figure it out yet. It's not in my COM list. (Console app, targeting .NET 4.5.) – zimdanen Jul 14 '15 at 18:39
  • I don't have a setup where I can test this myself at the moment, but you should be able to lift the code off the page I link to first. – 500 - Internal Server Error Jul 14 '15 at 19:04
  • Check client side config, it should be set as Security Mode="Transport". – Nitin Midha Jul 14 '15 at 21:21
  • @500-InternalServerError: Are you saying to extern the method in the first link myself? – zimdanen Jul 15 '15 at 21:40
  • @NitinMidha: The client side is all configured via code; you can see that the securityMode is already set to Transport in the snippet I pasted. – zimdanen Jul 15 '15 at 21:44
  • @zimdanen: yes, that's what I am saying. If it fails I think the call returns an error code, which may be more descriptive, but which is swallowed by the managed wrapper. – 500 - Internal Server Error Jul 15 '15 at 21:56
  • @500-InternalServerError: I assume, for the `formatName`, I provide something like `.\private$\QeuueName`? What do I provide for `properties`? – zimdanen Jul 16 '15 at 16:41
  • Just create an empty object, as they do in the reference source I link to. – 500 - Internal Server Error Jul 16 '15 at 19:30
  • Okay, just want to make sure this is right before I send it to our ops web team to run in the environment. I get -1072824290 when I run it locally. You're just looking to see if it returns anything at all or if it errors, right? – zimdanen Jul 16 '15 at 20:48
  • Nope, that's an error! I see. Will get back to you once I get the name right. – zimdanen Jul 16 '15 at 20:56
  • @500-InternalServerError: Okay, if I use `DIRECT=OS:.\private$\BulkUpdatesDeadLetter`, I get -1072824259, which is `MQ_ERROR_ILLEGAL_MQQUEUEPROPS`. [Returned when no properties are specified in the MQQUEUEPROPS structure, or the pQueueProps parameter is set to NULL.](https://msdn.microsoft.com/en-us/library/ms700106(v=vs.85).aspx) – zimdanen Jul 16 '15 at 21:01
  • Odd, because that's exactly what the linked reference source does: create an empty properties structure, pin it, and pass the pinned pointer to the function. – 500 - Internal Server Error Jul 16 '15 at 22:46
  • @500-InternalServerError: It looks like there is endless code to copy to get this to work. Where do Fx/FxTrace/DiagnosticUtility come from? Is FxTrace the one I can find in System.Xaml.Hosting by searching? – zimdanen Jul 17 '15 at 18:13
  • @zimdanen refer to this https://msdn.microsoft.com/en-us/library/ms789008(v=vs.110).aspx – Feras Salim Jul 19 '15 at 22:57
  • @FerasSalim: That's the basics of establishing communication with MSMQ. I already have communication working everywhere, but it stopped in this one environment, and the error message talks about the dead letter queue. – zimdanen Jul 20 '15 at 15:10

1 Answers1

3

The following code is provided by Microsoft corporation in the article BindingsSection.cs source code in C# .NET

  namespace System.ServiceModel.Configuration 
    {
        using System.Configuration; 
        using System.ServiceModel.Channels; 
        using System.ServiceModel;
        using System.Collections.Generic; 
        using System.Globalization;
        using System.Reflection;
        using System.Xml;
        using System.Security; 

        public sealed partial class BindingsSection : ConfigurationSection, IConfigurationContextProviderInternal 
        { 
            static Configuration configuration = null;
            ConfigurationPropertyCollection properties; 

            public BindingsSection() { }

            Dictionary<string, bindingcollectionelement=""> BindingCollectionElements 
            {
                get
                { 
                    Dictionary<string, bindingcollectionelement=""> bindingCollectionElements = new Dictionary<string, bindingcollectionelement="">();

                    foreach (ConfigurationProperty property in this.Properties)
                    {
                        bindingCollectionElements.Add(property.Name, this[property.Name]);
                    } 

                    return bindingCollectionElements; 
                } 
            }

            new public BindingCollectionElement this[string binding]
            {
                get
                { 
                    return (BindingCollectionElement)base[binding];
                } 
            } 

            protected override ConfigurationPropertyCollection Properties 
            {
                get
                {
                    if (this.properties == null) 
                    {
                        this.properties = new ConfigurationPropertyCollection(); 
                    } 

                    this.UpdateBindingSections(); 
                    return this.properties;
                }
            }

            [ConfigurationProperty(ConfigurationStrings.BasicHttpBindingCollectionElementName, Options = ConfigurationPropertyOptions.None)]
            public BasicHttpBindingCollectionElement BasicHttpBinding 
            { 
                get { return (BasicHttpBindingCollectionElement)base[ConfigurationStrings.BasicHttpBindingCollectionElementName]; }
            } 

            // This property should only be called/set from BindingsSectionGroup TryAdd
            static Configuration Configuration
            { 
                get { return BindingsSection.configuration; }
                set { BindingsSection.configuration = value; } 
            } 

            [ConfigurationProperty(ConfigurationStrings.CustomBindingCollectionElementName, Options = ConfigurationPropertyOptions.None)] 
            public CustomBindingCollectionElement CustomBinding
            {
                get { return (CustomBindingCollectionElement)base[ConfigurationStrings.CustomBindingCollectionElementName]; }
            } 

            [ConfigurationProperty(ConfigurationStrings.MsmqIntegrationBindingCollectionElementName, Options = ConfigurationPropertyOptions.None)] 
            public MsmqIntegrationBindingCollectionElement MsmqIntegrationBinding 
            {
                get { return (MsmqIntegrationBindingCollectionElement)base[ConfigurationStrings.MsmqIntegrationBindingCollectionElementName]; } 
            }

            [ConfigurationProperty(ConfigurationStrings.NetPeerTcpBindingCollectionElementName, Options = ConfigurationPropertyOptions.None)]
            public NetPeerTcpBindingCollectionElement NetPeerTcpBinding 
            {
                get { return (NetPeerTcpBindingCollectionElement)base[ConfigurationStrings.NetPeerTcpBindingCollectionElementName]; } 
            } 

            [ConfigurationProperty(ConfigurationStrings.NetMsmqBindingCollectionElementName, Options = ConfigurationPropertyOptions.None)] 
            public NetMsmqBindingCollectionElement NetMsmqBinding
            {
                get { return (NetMsmqBindingCollectionElement)base[ConfigurationStrings.NetMsmqBindingCollectionElementName]; }
            } 

            [ConfigurationProperty(ConfigurationStrings.NetNamedPipeBindingCollectionElementName, Options = ConfigurationPropertyOptions.None)] 
            public NetNamedPipeBindingCollectionElement NetNamedPipeBinding 
            {
                get { return (NetNamedPipeBindingCollectionElement)base[ConfigurationStrings.NetNamedPipeBindingCollectionElementName]; } 
            }

            [ConfigurationProperty(ConfigurationStrings.NetTcpBindingCollectionElementName, Options = ConfigurationPropertyOptions.None)]
            public NetTcpBindingCollectionElement NetTcpBinding 
            {
                get { return (NetTcpBindingCollectionElement)base[ConfigurationStrings.NetTcpBindingCollectionElementName]; } 
            } 

            [ConfigurationProperty(ConfigurationStrings.WSFederationHttpBindingCollectionElementName, Options = ConfigurationPropertyOptions.None)] 
            public WSFederationHttpBindingCollectionElement WSFederationHttpBinding
            {
                get { return (WSFederationHttpBindingCollectionElement)base[ConfigurationStrings.WSFederationHttpBindingCollectionElementName]; }
            } 

            [ConfigurationProperty(ConfigurationStrings.WS2007FederationHttpBindingCollectionElementName, Options = ConfigurationPropertyOptions.None)] 
            public WS2007FederationHttpBindingCollectionElement WS2007FederationHttpBinding 
            {
                get { return (WS2007FederationHttpBindingCollectionElement)base[ConfigurationStrings.WS2007FederationHttpBindingCollectionElementName]; } 
            }

            [ConfigurationProperty(ConfigurationStrings.WSHttpBindingCollectionElementName, Options = ConfigurationPropertyOptions.None)]
            public WSHttpBindingCollectionElement WSHttpBinding 
            {
                get { return (WSHttpBindingCollectionElement)base[ConfigurationStrings.WSHttpBindingCollectionElementName]; } 
            } 

            [ConfigurationProperty(ConfigurationStrings.WS2007HttpBindingCollectionElementName, Options = ConfigurationPropertyOptions.None)] 
            public WS2007HttpBindingCollectionElement WS2007HttpBinding
            {
                get { return (WS2007HttpBindingCollectionElement)base[ConfigurationStrings.WS2007HttpBindingCollectionElementName]; }
            } 

            [ConfigurationProperty(ConfigurationStrings.WSDualHttpBindingCollectionElementName, Options = ConfigurationPropertyOptions.None)] 
            public WSDualHttpBindingCollectionElement WSDualHttpBinding 
            {
                get { return (WSDualHttpBindingCollectionElement)base[ConfigurationStrings.WSDualHttpBindingCollectionElementName]; } 
            }

            public static BindingsSection GetSection(Configuration config)
            { 
                if (config == null)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("config"); 
                }

                return (BindingsSection)config.GetSection(ConfigurationStrings.BindingsSectionGroupPath);
            }

            public List<bindingcollectionelement> BindingCollections 
            {
                get
                { 
                    List<bindingcollectionelement> bindingCollections = new List<bindingcollectionelement>();
                    foreach (ConfigurationProperty property in this.Properties) 
                    {
                        bindingCollections.Add(this[property.Name]);
                    }

                    return bindingCollections;
                } 
            } 

            internal static bool TryAdd(string name, Binding binding, Configuration config, out string bindingSectionName) 
            {
                bool retval = false;
                BindingsSection.Configuration = config;
                try
                {
                    retval = BindingsSection.TryAdd(name, binding, out bindingSectionName); 
                } 
                finally
                { 
                    BindingsSection.Configuration = null;
                }
                return retval;
            } 

            internal static bool TryAdd(string name, Binding binding, out string bindingSectionName) 
            { 
                // TryAdd built on assumption that BindingsSectionGroup.Configuration is valid.
                // This should be protected at the callers site.  If assumption is invalid, then 
                // configuration system is in an indeterminate state.  Need to stop in a manner that
                // user code can not capture.
                if (null == BindingsSection.Configuration)
                { 
                    DiagnosticUtility.DebugAssert("The TryAdd(string name, Binding binding, Configuration config, out string binding) variant of this function should always be called first. The Configuration object is not set.");
                    DiagnosticUtility.FailFast("The TryAdd(string name, Binding binding, Configuration config, out string binding) variant of this function should always be called first. The Configuration object is not set."); 
                } 

                bool retval = false; 
                string outBindingSectionName = null;
                BindingsSection sectionGroup = BindingsSection.GetSection(BindingsSection.Configuration);
                sectionGroup.UpdateBindingSections();
                foreach (string sectionName in sectionGroup.BindingCollectionElements.Keys) 
                {
                    BindingCollectionElement bindingCollectionElement = sectionGroup.BindingCollectionElements[sectionName]; 

                    // Save the custom bindings as the last choice
                    if (!(bindingCollectionElement is CustomBindingCollectionElement)) 
                    {
                        MethodInfo tryAddMethod = bindingCollectionElement.GetType().GetMethod("TryAdd", BindingFlags.Instance | BindingFlags.NonPublic);
                        if (tryAddMethod != null)
                        { 
                            retval = (bool)tryAddMethod.Invoke(bindingCollectionElement, new object[] { name, binding, BindingsSection.Configuration });
                            if (retval) 
                            { 
                                outBindingSectionName = sectionName;
                                break; 
                            }
                        }
                    }
                } 
                if (!retval)
                { 
                    // Much of the time, the custombinding should come out ok. 
                    CustomBindingCollectionElement customBindingSection = CustomBindingCollectionElement.GetBindingCollectionElement();
                    retval = customBindingSection.TryAdd(name, binding, BindingsSection.Configuration); 
                    if (retval)
                    {
                        outBindingSectionName = ConfigurationStrings.CustomBindingCollectionElementName;
                    } 
                }

                // This little oddity exists to make sure that the out param is assigned to before the method 
                // exits.
                bindingSectionName = outBindingSectionName; 
                return retval;
            }

            /// <securitynote> 
            /// Critical - uses SecurityCritical method UnsafeLookupCollection which elevates
            /// Safe - does not leak config objects 
            /// </securitynote> 
            [SecurityCritical, SecurityTreatAsSafe]
            void UpdateBindingSections() 
            {
                ExtensionElementCollection bindingExtensions = ExtensionsSection.UnsafeLookupCollection(ConfigurationStrings.BindingExtensions, ConfigurationHelpers.GetEvaluationContext(this));

                // Extension collections are additive only (BasicMap) and do not allow for <clear> 
                // or <remove> tags, nor do they allow for overriding an entry.  This allows us
                // to optimize this to only walk the binding extension collection if the counts 
                // mismatch. 
                if (bindingExtensions.Count != this.properties.Count)
                { 
                    foreach (ExtensionElement bindingExtension in bindingExtensions)
                    {
                        if (null != bindingExtension)
                        { 
                            if (!this.properties.Contains(bindingExtension.Name))
                            { 
                                ConfigurationProperty property = new ConfigurationProperty(bindingExtension.Name, 
                                    Type.GetType(bindingExtension.Type, true),
                                    null, 
                                    ConfigurationPropertyOptions.None);

                                this.properties.Add(property);
                            } 
                        }
                    } 
                } 
            }

            /// <securitynote>
            /// Critical - uses SecurityCritical method UnsafeGetAssociatedBindingCollectionElement which elevates
            /// Safe - does not leak config objects
            /// </securitynote> 
            [SecurityCritical, SecurityTreatAsSafe]
            internal static void ValidateBindingReference(string binding, string bindingConfiguration, ContextInformation evaluationContext, ConfigurationElement configurationElement) 
            { 
                // ValidateBindingReference built on assumption that evaluationContext is valid.
                // This should be protected at the callers site.  If assumption is invalid, then 
                // configuration system is in an indeterminate state.  Need to stop in a manner that
                // user code can not capture.
                if (null == evaluationContext)
                { 
                    DiagnosticUtility.DebugAssert("ValidateBindingReference() should only called with valid ContextInformation");
                    DiagnosticUtility.FailFast("ValidateBindingReference() should only called with valid ContextInformation"); 
                } 

                if (!String.IsNullOrEmpty(binding)) 
                {
                    BindingCollectionElement bindingCollectionElement = null;

                    if (null != evaluationContext) 
                    {
                        bindingCollectionElement = ConfigurationHelpers.UnsafeGetAssociatedBindingCollectionElement(evaluationContext, binding); 
                    } 
                    else
                    { 
                        bindingCollectionElement = ConfigurationHelpers.UnsafeGetBindingCollectionElement(binding);
                    }

                    if (bindingCollectionElement == null) 
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.GetString(SR.ConfigInvalidSection, 
                            ConfigurationHelpers.GetBindingsSectionPath(binding)), 
                            configurationElement.ElementInformation.Source,
                            configurationElement.ElementInformation.LineNumber)); 
                    }

                    if (!String.IsNullOrEmpty(bindingConfiguration))
                    { 
                        if (!bindingCollectionElement.ContainsKey(bindingConfiguration))
                        { 
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.GetString(SR.ConfigInvalidBindingName, 
                                bindingConfiguration,
                                ConfigurationHelpers.GetBindingsSectionPath(binding), 
                                ConfigurationStrings.BindingConfiguration),
                                configurationElement.ElementInformation.Source,
                                configurationElement.ElementInformation.LineNumber));
                        } 
                    }
                } 
            } 

            ContextInformation IConfigurationContextProviderInternal.GetEvaluationContext() 
            {
                return this.EvaluationContext;
            }

            /// <securitynote>
            ///   RequiresReview - the return value will be used for a security decision -- see comment in interface definition 
            /// </securitynote> 
            ContextInformation IConfigurationContextProviderInternal.GetOriginalEvaluationContext()
            { 
                DiagnosticUtility.DebugAssert("Not implemented: IConfigurationContextProviderInternal.GetOriginalEvaluationContext");
                return null;
            }
        } 
    }

    </remove></clear></bindingcollectionelement></bindingcollectionelement></bindingcollectionelement></string,></string,></string,>
Jaffer Wilson
  • 7,029
  • 10
  • 62
  • 139
  • try this code .. hope this will definitely help you to get your query solved – Jaffer Wilson Jul 21 '15 at 09:17
  • I'm a bit confused as to what you want me to do with this code. It is just the definition of the `BindingsSection` class, which is part of the WCF infrastructure provided by Microsoft. – zimdanen Jul 21 '15 at 16:01