Take the 2-minute tour ×

I'm building a DLL which should be used by some other applications I'm building. Part of the DLL functionality is to log all SOAP transactions.

I've found this explanation on how to catch SOAP transactions in C#. http://blog.encoresystems.net/articles/how-to-capture-soap-envelopes-when-consuming-a-web-service.aspx

My problem is that it required to add the following to the app.config (end of page of the link).

        <add type="Encore.PayPal.Soap.TraceExtension, Encore.PayPal.Soap" priority="1" group="0" />

I don't want it to be a requirement for all that uses my DLL to add this to there app.config.

Is there a way to do it on the fly as the DLL is loaded ?

share|improve this question

1 Answer 1

up vote 2 down vote accepted

I found a similar question on the MSDN forums: Programmatically registering a SOAP Extension

/// <summary>  
/// Programatically registers a <see cref="SoapExtension"/> at runtime with the specified  
/// <see cref="SoapExtensionTypeElement.Priority"/> and <see cref="SoapExtensionTypeElement.Group"/> settings.  
/// </summary>  
/// <param name="type">The <see cref="Type"/> of the <see cref="SoapExtension"/> to register.</param>  
/// <param name="priority">  
/// A value that indicates the relative order in which this SOAP extension runs when multiple SOAP extensions are  
/// specified. Within each group the priority attribute distinguishes the overall relative priority of the SOAP   
/// extension. A lower priority number indicates a higher priority for the SOAP extension. The lowest possible   
/// value for the priority attribute is 1.  
/// </param>  
/// <param name="group">  
/// The relative priority group (e.g. Low or High) in which this SOAP extension runs when multiple SOAP extensions   
/// are configured to run.  
/// </param>  
[ReflectionPermission(SecurityAction.Demand, Unrestricted = true)]  
public static void RegisterSoapExtension(Type type, int priority, PriorityGroup group)  
    if (!type.IsSubclassOf(typeof(SoapExtension)))  
        throw new ArgumentException("Type must be derived from SoapException.", "type");  

    if (priority < 1)  
        throw new ArgumentOutOfRangeException("priority", priority, "Priority must be greater or equal to 1.");  

    // get the current web services settings...  
    WebServicesSection wss = WebServicesSection.Current;  

    // set SoapExtensionTypes collection to read/write...  
    FieldInfo readOnlyField = typeof(System.Configuration.ConfigurationElementCollection).GetField("bReadOnly", BindingFlags.NonPublic | BindingFlags.Instance);  
    readOnlyField.SetValue(wss.SoapExtensionTypes, false);  

    // inject SoapExtension...  
    wss.SoapExtensionTypes.Add(new SoapExtensionTypeElement(type, priority, group));  

    // set SoapExtensionTypes collection back to readonly and clear modified flags...  
    MethodInfo resetModifiedMethod = typeof(System.Configuration.ConfigurationElement).GetMethod("ResetModified", BindingFlags.NonPublic | BindingFlags.Instance);  
    resetModifiedMethod.Invoke(wss.SoapExtensionTypes, null);  
    MethodInfo setReadOnlyMethod = typeof(System.Configuration.ConfigurationElement).GetMethod("SetReadOnly", BindingFlags.NonPublic | BindingFlags.Instance);  
    setReadOnlyMethod.Invoke(wss.SoapExtensionTypes, null);  

You need to call this method before your client/server is instantiated.

RegisterSoapExtension(typeof(TraceExtension), 1, PriorityGroup.Low);
PaypalClient cli = new PaypalClient();
share|improve this answer
Thanks, That's exactly what I was looking for. –  Roee Gavirel Nov 27 '11 at 14:00
step 2, I don't know if this is something you have tried your own or not. but if you did, do you know if this is a thread safe or not. meaning, if I have 2 threads and I run this "Register" in one of them. will he capture the SOAP made from the second thread ? –  Roee Gavirel Nov 27 '11 at 14:42
I don't think it is thread-safe. You could synchronize it with lock(obj) { ... }, or do this before starting the threads. –  Markus Jarderot Nov 27 '11 at 14:47

Your Answer


