February 2005 Blog Posts

The new ASMX runtime in .NET 2.0 will support SOAP 1.2. How useful this turns out to be remains to be seen since almost everyone is using SOAP 1.1 at the moment. By default, web services will have both SOAP 1.1 and SOAP 1.2 bindings exposed on the server side and will accept messages for either. The following excerpt from the WSDL file of a simple service shows the two bindings:

<wsdl:binding name="SimpleServiceSoap" type="tns:SimpleServiceSoap">
  <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" /> 
  <wsdl:operation name="Hello">
    <soap:operation soapAction="urn:simple/Hello" style="document" /> 
    <wsdl:input>
      <soap:body use="literal" /> 
    </wsdl:input>
    <wsdl:output>
      <soap:body use="literal" /> 
    </wsdl:output>
  </wsdl:operation>
</wsdl:binding>
<wsdl:binding name="SimpleServiceSoap12" type="tns:SimpleServiceSoap">
  <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" /> 
  <wsdl:operation name="Hello">
    <soap12:operation soapAction="urn:simple/Hello" style="document" /> 
    <wsdl:input>
      <soap12:body use="literal" /> 
    </wsdl:input>
    <wsdl:output>
      <soap12:body use="literal" /> 
    </wsdl:output>
  </wsdl:operation>
</wsdl:binding>

You can control whether you want these bindings enabled through the web.config file. The following configuration file removes the SOAP 1.2 binding:

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

Replace "HttpSoap1.2" with "HttpSoap" to remove the SOAP 1.1 binding.

On the client side, WSDL.EXE generates SOAP 1.1 proxy code by default. There is a /protocol command line option to WSDL.EXE that allows you to specify which version to use. /protocol:SOAP generates a SOAP 1.1 client and /protocol:SOAP12 generates a SOAP 1.2 client:

C:\>wsdl /o:simpleproxy.cs /protocol:SOAP http://localhost/simple.asmx
Microsoft (R) Web Services Description Language Utility
[Microsoft(R) .NET Framework, Version 2.0.40607.85]
Copyright (C) Microsoft Corporation. All rights reserved.

Writing file 'simpleproxy.cs'.

C:\>wsdl /o:simpleproxy12.cs /protocol:SOAP12 http://localhost/simple.asmx
Microsoft (R) Web Services Description Language Utility
[Microsoft(R) .NET Framework, Version 2.0.40607.85]
Copyright (C) Microsoft Corporation. All rights reserved.

Writing file 'simpleproxy12.cs'.

C:\>

The System.Web.Services.Protocols.SoapHttpClientProtocol class that is used as the base class of the generated client proxies has a new property SoapVersion. This is set to SoapProtocolVersion.Soap12 to indicate that SOAP 1.2 should be used. The correct binding name is also chosen from the WSDL (SimpleServiceSoap vs. SimpleServiceSoap12 from the WSDL example above).

Note: this post was written against .NET 2.0 Beta 1. Expect some subtle changes to the names of things in Beta 2 onwards.

Fritz Onion has a great post about asynchronous web pages in ASP.NET 2.0 [via Mike Taulty].

In my last post, I described how .NET 2.0 will check your web services for conformance to the Basic Profile (v1.0 in Beta 1 and v1.1 from Beta 2 onwards). When you create a web service client proxy using WSDL.EXE, the service is also checked for BP compliance. If I generate a proxy for my simple non-compliant web service then I get the following output:

C:\>wsdl /o:simpleproxy.cs http://localhost/simple.asmx
Microsoft (R) Web Services Description Language Utility
[Microsoft(R) .NET Framework, Version 2.0.40607.85]
Copyright (C) Microsoft Corporation. All rights reserved.

Warning: This web reference does not conform to WS-I Basic Profile v1.0.
R2706: A wsdl:binding in a DESCRIPTION MUST use the value of "literal" for
the use attribute in all soapbind:body, soapbind:fault, soapbind:header and
soapbind:headerfault elements.
- Operation 'Hello' on binding 'SimpleServiceSoap' from namespace 'urn:simple'.

Writing file 'simpleproxy.cs'.

C:\>

The generated proxy will still work as normal to communicate with the web service if possible. The message is just a warning for your information, which you may communicate to the web service author. Clients generated with WSDL.EXE will always be BP compliant unless something appears in the service's WSDL that prevents this (for example using SOAP encoding).

ASP.NET web services (commonly known as ASMX web services) have been a part of the .NET Framework from the beginning in v1.0 when it was still early days in the web services world. A number of enhancements have been made to ASMX in version 2.0 of the framework and one in particular is aimed at helping developers achieve improved interoperability with other web service platforms.

The original SOAP 1.1 and WSDL 1.1 specifications were very broadly defined and this has made interop a difficult goal. Through a standards organisation called the WS-I, a specification called Basic Profile Version 1.0 (BP) was created that defines a profile or subset of the SOAP and WSDL specs that should be used. By providing a set of rules that narrows the scope of web service implementations there is a greater chance that different platforms can work together successfully. ASMX 2.0 includes checks against all the BP rules to determine if your web service is compliant.

Existing web services from the 1.0 or 1.1 version of .NET when run with the 2.0 version of the framework will be checked to see if they are BP compliant. A warning will be given on the documentation page if the web service is non-compliant but either way the service will continue to work as it did with previous versions. Any warnings are just for information and can be disabled if you choose. The following file, simple.asmx, demonstrates this:

<%@ WebService Language="C#" Class="SimpleService" %>

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

[WebService(Namespace="urn:simple")]
public class SimpleService {

        [WebMethod, SoapRpcMethod]
        public string Hello(string s) {
                return string.Format("Hello, {0}!",s);
        }

}

The Hello method has the SoapRpcMethod attribute causing it to use a SOAP rpc/encoded binding. This is not allowed by the Basic Profile and so the documentation page for the web service gives the warning "This web service does not conform to WS-I Basic Profile v1.0." The specific BP rule that has been violated is quoted together with a recommendation for what to do to make the service compliant. If we remove the SoapRpcMethod attribute, the warning goes away and the service conforms.

New web services built for the 2.0 framework can explicitly declare their BP compliance using the ComformanceClaims property of the WebServiceBinding attribute:

<%@ WebService Language="C#" Class="SimpleService" %>

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

[WebService(Namespace="urn:simple")]
[WebServiceBinding(ConformanceClaims=WsiClaims.BP10,EmitConformanceClaims=true)]
public class SimpleService {

        [WebMethod]
        public string Hello(string s) {
                return string.Format("Hello, {0}!",s);
        }

}

The WebServiceBinding attribute adds a claim for conformance to the Basic Profile 1.0. The EmitConfirmanceClaims property exposes this claim in a machine readable way by including the following XML as part of the WSDL for the web service:

<wsdl:documentation>
  <wsi:Claim conformsTo="http://ws-i.org/profiles/basic/1.0" xmlns:wsi="http://ws-i.org/schemas/conformanceClaim/" /> 
</wsdl:documentation>

Asserting Basic Profile 1.0 conformance using the WebServiceBinding attribute enforces the rules checking. If the service is non-conformant then an exception will be generated rather than the warning if the attribute is not present. This makes sense: you can't assert conformance and then not achieve it. As with the warning, the exception message tells you which rules weren't satisfied and suggests how to fix the problem.

As different platforms address conformance to the Basic Profile it will be much easier to build interoperable web services and clients right first time.

Update: This code is written with Beta 1 of .NET 2.0 which uses Basic Profile v1.0. Beta 2 will use the Basic Profile 1.1.

The WSE 2.0 SP3 download was released today. There is also a Runtime Redistributable to bundle with your apps.

Managed C++ takes some time getting used to with its __everything modifiers. C++/CLI is the new managed C++ what will ship with .NET 2.0 and Visual Studio 2005. For some reason it reminds me of Pascal with its ^ tracking handles. Stan Lippman has written a guide to the differences between the two and how to migrate to C++/CLI.

Our free Microsoft Security E-Learning Clinics follow the same content outline as our Security Webcasts, but deliver that information via a learner-centered format that offers unique user benefits. With an E-Learning Clinic, you can access the security topic you want, when you want it, and learn at your own pace.

The File Checksum Integrity Verifier (FCIV) is a command-prompt utility that computes and verifies cryptographic hash values of files. FCIV can compute MD5 or SHA-1 cryptographic hash values. These values can be displayed on the screen or saved in an XML file database for later use and verification.

This post is really a bookmark for me because I regularly seem to come back to the question of wanting to update environment variables and trying to remember the windows message to use to propagate the changes. There is a knowledge base article that covers this, and the message to broadcast is WM_SETTINGCHANGE.