Help! How do I send extensible data in my WS-Eventing Subscribe?

Reader Nitin raises a good question: how does an app put extensible data into the Subscribe message that's used to set up events?

Example scenario: WSD Scan
Nitin's question asks specifically about the WSD Scan protocol built into Vista and Servier 2008, so I'll use that as an example.  The scan protocol defines a ScanAvailableEvent (and includes a definition for this event in the WSDL) and the specification text says that when a client subscribes to the ScanAvailableEvent, it may supply a ScanDestinations element inside the extensible section of the Subscribe message.  How this ScanDestination element works is largely unimportant in illustrating my point, but you can imagine it's a way for the client to send some information to the scanner for use in sending events.

The thing is that WsdCodeGen (or any other WSDL processing tool) won't ever have any idea that ScanDestinations is associated with ScanAvailableEvent, since the relationship isn't defined in the WSDL or schema.  It's only included in the specification text, so there's no way to generate code that accepts ScanDestinations when subscribing for ScanAvailableEvent.

A tool that turned specification text into generated code could handle this problem; but if such a tool existed, I'd probably be out of a job.

What you can do to send custom data in Subscribe messages
Even though you can't get strongly typed generated code, WsdCodeGen does give you a way to pass DOM sections (WSDXML_ELEMENT and friends) into your generated Subscribe methods.

The way you do this is to open up your generated code by modifying your codegen.config file.  By default, you'll typically get structures that look like this:

HRESULT STDMETHODCALLTYPE
SubscribeToScanAvailableEvent
( IScannerServiceTypeEventNotify* eventSink
);

But by following a few steps, you can add two new methods to the SubscribeTo??? method so you can send extensible data in the request, and receive extensible data sent in the response:

HRESULT STDMETHODCALLTYPE
SubscribeToScanAvailableEvent
( IScanServiceNotify* eventSink
, /* [in] */ WSDXML_ELEMENT* any
, /* [out] */ WSDXML_ELEMENT** anyOut
);

Here are some easy steps to getting the versions of these methods that accept WSDXML_ELEMENT structures:

  1. Edit your codegen.config file
  2. Find any instances of any of the following elements:
  3. Add this attribute to each element: extensible="true"
    • For example, this would look like <SubscriptionFunctionDeclarations extensible="true"> ...
  4. Regenerate your code (wsdcodegen /generatecode codegen.config)
  5. Edit any calls you make to SubscribeTo??? methods so they include NULL parameters or WSDXML_ELEMENT structures.

And that's it!  Now you can send any XML you like in the Subscribe message, and extract the response contained in the SubscribeResponse.  Join me next time as I explain more about the WSDXML structures and how to properly build them.