May 14, 2011, 10:02 p.m.
posted by angryuser
Description FormattersSometimes, you will want the WSDL file created for your service to indicate that it will be modified by the SOAP extension running on it. Conversely, you will want the proxy generated for you from wsdl.exe to add the SOAP extension to any proxy classes it consumes that contain this indication. You can accomplish this with a ServiceDescriptionFormatter. This feature enables you to create a set of XML elements to go into the binding section of the WSDL that is automatically generated. This XML can be pretty much whatever you want, provided it doesn't make the WSDL document invalid. Imagine how powerful it would be to add a custom WSDL extension to our compression extension to indicate that the service is actually compressed SOAP! This is easy to do with .NET. The steps are as follows:
Listing 6.3 shows the operation binding class for the compression extension. A Sample Format Extension for the Compression Extension
[XmlFormatExtension("compress",
CompressionExtensionOperationBinding.Namespace,
typeof(OperationBinding))]
[XmlFormatExtensionPrefix("comp", CompressionExtensionOperationBinding.Namespace)] public class CompressionExtensionOperationBinding : ServiceDescriptionFormatExtension
{
public const string Namespace =
"http://keithba.com/CompressionExtension";
}
And here is the reflector class:
public class CompressionExtensionReflector :
SoapExtensionReflector
{
public override void ReflectMethod()
{
ProtocolReflector reflector = ReflectionContext; CompressionExtensionAttribute attr = (CompressionExtensionAttribute)reflector.Method.GetCustomAttribute( typeof(CompressionExtensionAttribute));
if (attr != null)
{
CompressionExtensionOperationBinding compress = new CompressionExtensionOperationBinding();
reflector.OperationBinding.Extensions.Add(compress);
}
}
}
Listing 6.4 shows the registration within web.config. Configuration for Extension Formatters and Reflectors
<webServices>
<soapExtensionReflectorTypes>
<add
type="CompressionService.CompressionExtensionReflector, CompressionService" />
</soapExtensionReflectorTypes>
<serviceDescriptionFormatExtensionTypes>
<add
type="CompressionService.CompressionExtensionOperationBinding, CompressionService" />
</serviceDescriptionFormatExtensionTypes>
</webServices>
Now, the WSDL contains a new element in the SOAP binding:
<binding name="Service1Soap" type="s0:Service1Soap">
<soap:binding
transport="http://schemas.xmlsoap.org/soap/http"
style="document" />
<operation name="SubmitPO">
<soap:operation soapAction="http://tempuri.org/SubmitPO" style="document" />
<comp:compress />
<input>
<soap:body use="literal" />
</input>
<output>
<soap:body use="literal" />
</output>
</operation>
</binding>
The reverse is also possible! We can create an importer class to be run when wsdl.exe or the Add Web Reference dialog box in VS.NET imports the WSDL. Now, to do this, we need to strong name our compression extension assembly, and install it to the entire machine. Then we can add registration within the machine.config to use these classes when importing WSDLs. Listing 6.5 shows the importer class. Importer Class for the Compression Extension
public class CompressionExtensionImporter : SoapExtensionImporter
{
public override void ImportMethod( CodeAttributeDeclarationCollection metadata)
{
SoapProtocolImporter importer = ImportContext;
CodeAttributeDeclaration attr = new CodeAttributeDeclaration(typeof(CompressionExtensionAttribute) .FullName);
metadata.Add(attr);
}
}
Listing 6.6 shows the machine.config entry. Configuration Entries in machine.config for Registering an Importer
<webServices>
<protocols>
<add name="HttpSoap"/>
<add name="HttpPost"/>
<add name="HttpGet"/>
<add name="Documentation"/>
</protocols>
<soapExtensionTypes>
</soapExtensionTypes>
<soapExtensionImporterTypes>
<add
type="CompressionService.CompressionExtensionImporter, CompressionService" />
</soapExtensionImporterTypes>
<serviceDescriptionFormatExtensionTypes> <add
type="CompressionService.CompressionExtensionOperationBinding,
CompressionService" />
</serviceDescriptionFormatExtensionTypes>
<wsdlHelpGenerator href="DefaultWsdlHelpGenerator.aspx"/>
</webServices>
|
- Comment