如何将 "catch-all" xsd:any 元素注入到 WSDL 描述的每个响应对象中?

How to inject "catch-all" xsd:any element into every response object described by a WSDL?

我们有一个由 C# 和 Java 客户端使用的 SOAP Web 服务。

问题在于,当我们升级 Web 服务时,客户端并不急于重新生成代理,因此为旧版本生成的代理代码可能会被用于使用较新版本的服务。

碰巧,向响应对象添加新的 属性 会破坏使用已生成的旧代理代码的 Java 客户端。显然,Java 在其对 WSDL 的解释上非常严格,并且当 属性 到达时 WSDL 中不存在的异常失败。至少,这是我们观察到的由 apache 轴生成的代理代码。 C# 客户端很好 - 新属性被简单地忽略了。

我正在想办法解决这个问题。一种似乎可行的解决方案是将 xsd:any 属性 注入到 WSDL 中找到的每个响应对象中。据我了解,各种 Java 实现将把它用作所有未知属性的 "catch-all" 属性 (当然,客户将不得不重新生成他们的代理来使用这些 xsd:any 定义,但一旦完成,新的属性将抓住并破坏它们的代码)

问题是我如何才能在 WSDL 中注入这些 xsd:any 属性,而不实际向响应对象添加真正的 "catch-all" 属性?

我们的 Web 服务是使用 WCF 实现的。

显然,实现它的唯一方法是引入一个新的端点行为,该行为也实现了 IWsdlExportExtension 接口。那么,我们开始吧:

public class WSDLFilterBehavior : IWsdlExportExtension, IEndpointBehavior
{
    public void ExportContract(WsdlExporter exporter, WsdlContractConversionContext context)
    {
        // never called
    }

    public void ExportEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext context)
    {
        var schemas = exporter.GeneratedXmlSchemas.Schemas(@"http://Abc/Services/Data");
        foreach (XmlSchema schema in schemas)
        {
            for (int i = schema.Items.Count - 1; i >= 0; --i)
            {
                // Do some other processing ...

                var schemaComplexType = schema.Items[i] as XmlSchemaComplexType;
                if (schemaComplexType == null)
                {
                    continue;
                }

                XmlSchemaSequence xmlSchemaSequence;
                var xmlSchemaContentModel = schemaComplexType.ContentModel;
                if (xmlSchemaContentModel == null)
                {
                    if (schemaType.Name.StartsWith("ArrayOf"))
                    {
                        continue;
                    }
                    xmlSchemaSequence = schemaComplexType.Particle as XmlSchemaSequence;
                }
                else
                {
                    var xmlSchemaComplexContentExtension = xmlSchemaContentModel.Content as XmlSchemaComplexContentExtension;
                    if (xmlSchemaComplexContentExtension == null)
                    {
                        continue;
                    }

                    xmlSchemaSequence = xmlSchemaComplexContentExtension.Particle as XmlSchemaSequence;
                }

                if (xmlSchemaSequence == null)
                {
                    continue;
                }

                var xmlSchemaObject = new XmlSchemaAny
                {
                    MinOccurs = 0
                };
                xmlSchemaSequence.Items.Add(xmlSchemaObject);
            }
        }
    }

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
        // not needed
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        // not needed
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint,EndpointDispatcher dispatcher)
    {
        // not needed
    }

    public void Validate(ServiceEndpoint endpoint)
    {
        // not needed
    }
}

它起作用了,它在所有元素中注入 xs:any(不是 xsd:any,但我想它是相同的),除了那些不是从任何其他类型派生并开始的元素"ArrayOf".