Add or remove SOAP 1.2 for ASMX services

ASMX 2.0 supports both SOAP 1.1 and SOAP 1.2.  But how do you use SOAP 1.2 with your ASMX services? 

Suppose you have a web service using ASMX 2.0 and you want to explicitly consume a SOAP 1.2 web service. 

The documentation for adding or removing SOAP 1.2 support in a web service doesn't seem up-to-sync yet.  But, the error messages you will receive when you try to put a wrong value in the "name" attribute in the protocols section seems up-to-date :)  The valid values for the add element for are documented in the System.Web.Services.Configuration.WebServiceProtocols enum:

Member name Description
AnyHttpSoap Any version of the HTTP SOAP protocol. 
Documentation The Web Services Documentation protocol. 
HttpGet The HTTP GET protocol. 
HttpPost The HTTP POST protocol. 
HttpPostLocalhost The HTTP POST LOCALHOST protocol. 
HttpSoap The HTTP SOAP protocol. 
HttpSoap12 The HTTP SOAP version 1.2 protocol. 
Unknown Unknown protocol. 

You can use these values in the webServices/protocols element to add and remove capability.  For instance, if you want to remove SOAP 1.2 support for your service, you would include the following in your web.config:

 
<configuration>
    <system.web>
        <webServices >
            <protocols>
                <remove name="HttpSoap12"/>
            </protocols>      
        </webServices>
    </system.web> 
</configuration>

Similarly, if you want to remove support for SOAP 1.1 and only support SOAP 1.2, you would use the following config:

 
<configuration>
    <system.web>
        <webServices >
            <protocols>
                <remove name="HttpSoap"/>
            </protocols>      
        </webServices>
    </system.web> 
</configuration>

We can take advantage of SOAP 1.2 features, such as including sub-codes in the SoapException type. 

 
using System;
using System.Web.Services;
using System.Web.Services.Protocols;

namespace Contoso.Web.Services
{
    [WebServiceBinding(Namespace = "urn:contoso:com")]
    public interface IServiceContract
    {
        [WebMethod]
        string HelloWorld();
    }

    [WebService(Namespace = "urn:contoso:com")]
    public class Service : IServiceContract
    {
        public string HelloWorld()
        {
            throw new SoapException("SOAP 1.2 fault, baby",
                SoapException.ServerFaultCode,
                new SoapFaultSubCode(Soap12FaultCodes.ReceiverFaultCode));
        }
    }
}

That takes care of the service-side, but what about the client?  How do we take advantage of SOAP 1.2 from the client side?  By default, ASMX will support both SOAP 1.1 and SOAP 1.2, so how do you specify which version you want?  If the endpoint supports both SOAP 1.1 and SOAP 1.2, you can control this through the SoapVersion property of the generated client proxy, using the SoapProtocolVersion enum.

 localhost.IServiceContract s = new WindowsApplication1.localhost.IServiceContract();
s.SoapVersion = System.Web.Services.Protocols.SoapProtocolVersion.Soap12;
try
{
    MessageBox.Show(s.HelloWorld());
}
catch (System.Web.Services.Protocols.SoapException oops)
{
    MessageBox.Show(oops.SubCode.Code.ToString());
}

They have done some pretty cool stuff for ASMX 2.0.  If you haven't started looking around what's new for web services in .NET 2.0, I highly recommend you start with the SchemaImporterExtension Technology Sample to get a little excited about the possibilities in ASMX 2.0.