Click to Rate and Give Feedback
Related Articles
Here the author introduces SQL Server Data Services, which exposes its functionality over standard Web service interfaces.

By David Robinson (July 2008)
Here the author answers questions regarding the Entity Framework and provides an understanding of how and why it was developed.

By Elisa Flasko (July 2008)
Here we present techniques for programmatic and declarative data binding and display with Windows Presentation Foundation.

By Josh Smith (July 2008)
Systems that handle failure without losing data are elusive. Learn how to achieve systems that are both scalable and robust.

By Udi Dahan (July 2008)
More ...
Articles by this Author
This is the first installment of a new column about MSDN® projects: what we're doing, how we're doing it, and what we're learning along the way. It will be written by MSDN staff with the goal of sharing the team's experiences in solving the real-world business problems MSDN faces.

By Tim Ewald (February 2005)
Web Services exchange XML messages. Most of today's Web Service toolkits do their best to hide this fact from developers, by exposing a Web Service's behavior as method invocations against objects instead.

By Tim Ewald (March 2003)
ASP.NET is a flexible and extensible framework for server-side HTTP programming. While most people think of ASP.NET in terms of pages served, there is a lower-level infrastructure sitting beneath this page model. The underlying plumbing is based on a pipeline of app, module, and handler objects. Understanding how this pipeline works is key if you want to get the most out of ASP.NET as an HTTP server platform, while making your process more efficient, and keeping your server secure. This article introduces the architecture of the pipeline and shows how you can use it to add sophisticated functionality to an ASP.NET-based app.

By Tim Ewald and Keith Brown (September 2002)
The new version of COM+ that ships as part of Windows XP includes APIs for low-level context programming. These functions allow you to create contexts that use COM+ runtime services, independent of objects and without registering anything in the COM+ Catalog. Designed for advanced COM+ developers who understand the COM+ context model, these APIs make it easy to integrate runtime services with code in nonstandard ways. This article explains how these low-level context APIs work, discusses when you'd want to use them, and provides a .NET-based wrapper to make it simpler to use the APIs from C#.

By Craig Andera and Tim Ewald (April 2002)
The .NET Common Language Runtime (CLR) is Microsoft's next-generation component technology. The CLR is a replacement for COM, but not for COM+. COM+, now called .NET Enterprise Services, is the Microsoft object runtime environment for scalable system development. This article explains how to implement and deploy COM+ configured classes using the CLR, how to access object context and call context, and the rules for managing context-relative object references. Also discussed are ways to manage precious resources such as data connections and pooled objects, and the relationship between COM+ and the new .NET remoting architecture.

By Tim Ewald (October 2001)
More ...
Popular Articles
One-time passwords offer solutions to dictionary attacks, phishing, interception, and lots of other security breaches. Here's how it all works.

By Dan Griffin (May 2008)
OBA solution patterns help architects and developers build Office Business Applications (OBAs). This article introduces the seven core OBA solution patterns and applies one to a real-world problem.

By Steve Fox (March 2008)
Jamie Laflen extols the benefits of TDD when applied to database development—and supplies some useful techniques along the way.

By Jamie Laflen (Launch 2008)
Efficient parallel applications aren’t born by merely running an old app on a parallel processor machine. Tuning needs to be done if you’re to gain maximum benefit.

By Rahul V. Patil and Boby George (June 2008)
More ...
Read the Blog
There are many things called threat modeling. Rather than argue about which is "the one true way," a good practice is to consider your needs and what your skills, abilities, and schedules are, and then work with a method that's best for you. In the July 2008 issue of MSDN Magazine, ...
Read more!
Want to develop games for Xbox Live? Want to get paid for it, too? Click on over to the XNA Team Blog to learn more about their initial rollout of the XNA Creators Club for XNA Game Studio. ...
Read more!
The Microsoft Entity Data Model (EDM), based on Dr. Peter Chen's Entity Relationship (ER) model, is the driving force behind the ADO.NET Entity Framework. The EDM is also the feature that most significantly differentiates the Entity Framework from other ORM-style technologies in the marketplace. In the July 2008 issue of MSDN ...
Read more!
System.IO.File is a handy helper class for reading and writing data, but its methods support only synchronous operation. Is there an easy way to provide File’s functionality for asynchronous file I/O? In the July 2008 issue of MSDN Magazine, Stephen Toub walks through several ...
Read more!
Remember .NET Terrarium, the interactive game meant to introduce .NET development techniques? Well, the Windows SDK team has released the source code for .NET Terrarium 2.0 on CodePlex. You can read more about this release on the Windows SDK blog and at Microsoft ...
Read more!
The Enumerable class plays an important role in every LINQ query you create. Because the Enumerable class's extension methods can process many other classes—including Array and List—you can use methods of the Enumerable class not only to create LINQ queries, but also to manipulate the behavior of arrays and other data structures. In the July 2008 issue of MSDN ...
Read more!
More ...
House of Web Services
Mandatory Headers in ASP.NET Web Services
Tim Ewald

Code download available at: WebServices0305.exe (138 KB)
Browse the Code Online
The ASP.NET Web Services infrastructure includes support for programming with SOAP message headers. Unfortunately, the model for handling mandatory headers is flawed in that you need to write additional code so that a Web Service will not execute when a mandatory header is not processed. This column explores a specific problem that arises when you deal with mandatory SOAP handles and presents three solutions.

Mandatory Headers
SOAP messages may contain an optional header element from the SOAP namespace that, as stated in version 1.1 of the SOAP specification, "provides a flexible mechanism for extending a message in a decentralized and modular way without prior knowledge between the communicating parties." If present, the header element contains zero or more extension elements. An extension element may be marked with an optional mustUnderstand attribute, also from the SOAP namespace, indicating that the extension is mandatory. Figure 1 shows a sample message with a mandatory header. There is broad consensus that if a message receiver cannot process a mandatory header, it shouldn't process the message that contains it. Section 4.2.3 of the SOAP 1.1 specification suggests this, though the wording is a little vague:
If a header element is tagged with a SOAP mustUnderstand attribute with a value of '1', the recipient of that header entry either [must] obey the semantics (as conveyed by the fully qualified name of the element) and process correctly to those semantics, or [must] fail processing the message.
The Candidate Recommendation of the SOAP 1.2 specification (Part 1, section 2.4) fixes this problem, making the semantics of mandatory header processing very clear:
Mandatory SOAP header blocks are presumed to somehow modify the semantics of other SOAP header blocks or SOAP body elements. Therefore, for every mandatory SOAP header block targeted to a node, that node [must] either process the header block or refrain from processing the SOAP message at all, and instead generate a fault (see 2.6 Processing SOAP Messages and 5.4 SOAP Fault).
The ASP.NET Web Services plumbing includes a model for dealing with SOAP message headers. Unfortunately, it will allow a message to be processed even when it contains a mandatory header that the target method is not aware of or does not understand. While a fault will be generated, that doesn't happen until after your Web Service's code has run.

Mandatory Headers in ASP.NET
When the ASP.NET Web Services message dispatcher pulls a message apart, it uses the Body element's contents as the input parameters to a method invocation. Before the call is invoked, the contents of the header element (if any) may be deserialized into fields or properties of the target object. When the method runs, it can examine those fields or properties to see what headers a request message contained. The mapping of headers to properties or fields is optional. It is controlled using the value of System.Web.Services.Protocols.SoapHeaderAttribute. An example of this attribute is shown in Figure 2.
The Bar method is marked with a [SoapHeader] attribute that refers to the field named foo. The message dispatcher uses reflection and discovers that foo is an instance of Foo, a subclass of System.Web.Services.Protocols.SoapHeader. The dispatcher knows that all SoapHeader-derived types represent XML elements that may appear inside a request message's Header element. In this case, the [XmlRoot] attribute tells the dispatcher that the Foo class represents the Foo header from the http://msdn.microsoft.com/hows namespace. If that header appears in the header of a request message, the dispatcher then deserializes it into foo, thus making it available when Bar runs.
The SoapHeader base class (not to be confused with the SoapHeaderAttribute class) has a Boolean property called MustUnderstand. When the message dispatcher deserializes a header to a field or property, it checks to see if the header is mandatory (that is, it checks to see if the XML element has a mustUnderstand attribute whose value is either 1 or true). If it is, the dispatcher sets the SoapHeader.MustUnderstand property of the corresponding field or property to true. A method can examine this field to determine whether a header is mandatory or optional. A modified version of the Bar method that indicates whether a given Foo header was mandatory is shown in Figure 3.
The Web Services message dispatcher uses the SoapHeader.MustUnderstand property to tell your code that a given header is mandatory. But the SOAP specification says (vaguely or not, depending on the version) that if a mandatory header is not understood, a fault must be returned. That means that your code has to tell the dispatcher which headers it understood. To that end, the SoapHeader class has a second property called DidUnderstand. After a method call completes, the plumbing checks to see that all mandatory headers were understood by examining the DidUnderstand property of every mandatory SoapHeader-derived field or property used during the course of that method. If any of them have a MustUnderstand value of true and a DidUnderstand value of false, a fault is generated indicating that a mandatory header was not understood.
Figure 4 shows a third implementation of the Bar method that sets the DidUnderstand property of the foo field whenever the header is mandatory.

Expecting the Unexpected
At first glance, the MustUnderstand/DidUnderstand model may seem quite reasonable, but it has a significant limitation. The fundamental problem is that sometimes a client may send you mandatory headers that you were not expecting. For instance, my sample service may expect that the Foo header is optional, but it is coded to work correctly even if the client makes the header mandatory. This is easy to do with any header that your service is expecting. If you map a header to a field or property, just make sure that you set its DidUnderstand value to true whenever necessary. (Or, for safety's sake, set it to true in all cases—it won't hurt anything when a header is optional.)
But what about headers your service is not expecting? What if your client decides to slip in a mandatory header that your service has never heard of? If your service doesn't know about a header, it can't have mapped it to a specific field or property, and without that mapping there is no way to know if an unknown header is mandatory or to indicate that it was understood. At the same time, the plumbing has to enforce the SOAP specification's requirement that mandatory headers be processed correctly. So what happens?
Optimally, if the dispatcher detects a mandatory header that it can't map to a field or property, it will generate a fault instead of executing the code. Of course, this solution assumes that all mandatory headers are mapped to members within your class. And that isn't a bad assumption, given the general header processing model. Unfortunately, that's not the way it works. Instead, it's your job to map unknown headers to a field or property too and see if there are any mandatory headers you don't understand. The System.Web.Services.Protocols.SoapUnknownHeader class exists for this very purpose.
SoapUnknownHeader is a subclass of SoapHeader that the Web Services message dispatcher uses to represent any header that is not mapped to a specific field or property. Figure 5 shows a new version of my sample service that handles unknown headers.
As with other SoapHeader-derived types, you use the [SoapHeader] attribute to tell the message dispatcher what to do with any headers it can't otherwise process. The new version of the Bar method includes an attribute that tells the plumbing to map any unknown headers to the unknownHeaders field (which needs to be an array, in case there is more than one unknown header). The method begins with header processing code. First, it marks any mandatory Foo header (mapped to the foo field) as understood. Second, if the client sent any unknown headers (mapped to the unknownHeaders field), the method checks to see if any of them are mandatory. If it finds a mandatory header that it doesn't understand, it generates a MustUnderstand SOAP fault, as defined by the SOAP specification.
I'm willing to bet that the vast majority of ASP.NET Web Services that have been written and deployed to date do not explicitly check for unknown mandatory headers. That means that if a client sends a message with a mandatory header that has not been mapped to a field or property, there will be no way for a method to mark the header as understood. The result is that the dispatcher will generate a fault, but not until after the service executes! That's a direct violation of the SOAP specification, which says that a message must not be processed if mandatory headers are not understood. Practically, it means that your service will run, think that everything succeeded, and the client will receive a SOAP fault.
In short, if you want your service to conform to the SOAP specification, you need to do some work to handle unknown mandatory headers correctly.

Solving the Problem Once and for All
The SoapUnknownHeader code in Figure 5 solves the unknown mandatory header problem. However, including that code in every method you expose as a Web Service would be tedious. Luckily, a much simpler solution is possible: put it in a SoapExtension. The complete source code for a MustUnderstandExtension that detects the presence of unknown mandatory headers before a service executes is shown in Figure 6.
The ProcessMessage method scans all the headers found in a request message. It marks any known header as understood (that is, any header that has been mapped to a field or property of some subclass of SoapHeader other than SoapUnknownHeader). If it encounters an unknown mandatory header, it generates a SOAP MustUnderstand fault. This works even if a Web Service class does not include a field or property of type array of SoapUnknownHeader. This solution assumes that any known headers are in fact understood and that all mandatory headers are known, but, again, that's a reasonable assumption.
Given the general applicability of this extension, it makes sense to configure it for an entire Web Service, not just a single method. You can do that by adding the following configuration info to your web.config (or even machine.config) file:
<configuration>
  <system.web>
    <webServices>
      <soapExtensionTypes>
        <add type="MustUnderstand.MustUnderstandExtension,
                   MustUnderstand"
         priority="1" group="0" />
      </soapExtensionTypes>
    </webServices>
  </system.web>
</configuration>
Once that's done, the SampleService I just presented can revert to the one shown in Figure 7. Note that the code for processing unknown headers has been removed. With the MustUnderstandExtension in place, it is no longer necessary.

What About WSE?
A growing number of ASP.NET Web Services use the Web Services Enhancements (WSE) for the Microsoft® .NET Framework class library to add support for advanced Web Service protocols to their applications. The WSE has a very different model for processing headers, so if you're using it, you need to solve the mandatory unknown header problem a different way.
When a message arrives in a process, the WSE passes it through a series of input filters. Each input filter consumes one or more headers, removes them from the SOAP message, and exposes the data they carry as part of the SoapContext object model the WSE associates with the message. While it is possible to mix this header processing model with the ASP.NET Web Services header processing model, it's simpler to use the WSE model alone.
The easiest way to solve the mandatory unknown header problem with the WSE is to implement a custom input filter like the one shown in Figure 8. The MustUnderstandInputFilter uses XPath to see if a message contains a mandatory header. If it does, the filter generates a fault. The assumption is that by the time this input filter runs, previous input filters have processed and removed all mandatory headers from the message. (As a side note, it is important that anyone writing custom input filters for the WSE should adopt this approach; otherwise solving the mandatory unknown header problem will be more difficult than necessary.) If you configure this input filter using the standard WSE technique, it will run after all the WSE's built-in input filters. The configuration entry you need is shown in the following code:
<configuration>
  <microsoft.web.services>
    <filters>
      <input>
        <add type="MustUnderstandInputFilter, MustUnderstand" />
      </input>
    </filters>
  </microsoft.web.services>
</configuration>

Where are We?
Much of the power of the SOAP protocol comes from its extensibility. The header element is critical to the further development of Web Services; all the new advanced protocols for security, transactions, and other features are implemented using headers. However, this flexibility comes at a price. In loosely coupled systems, you need to expect that a client will send you things you didn't expect and you need to deal with them appropriately. In the case of mandatory headers, that means detecting and processing them before your Web Service code executes. While the ASP.NET Web Services plumbing does not do this automatically, its header processing model allows you to solve the problem yourself, and the solution is pretty simple.

Send your questions and comments for Tim to housews@microsoft.com.


Tim Ewaldis a Program Manager for XML Web Services at Microsoft. He is currently redesigning the MSDN architecture around Web Services, and writing and speaking about that technology. He is the author of Transactional COM+: Designing Scalable Applications (Addison-Wesley, 2001). Reach Tim at tewald@microsoft.com.

Page view tracker