WCF LOB Adapter, dealing with TypeMetadata and xsd:Include

|  Posted: September 16, 2011  |  Categories: General Technical

Say for example if you want to expose an operation called “AddOperation” which takes 2 input parameters of type “double” and returns a “double” value.

If you are building a standard WCF services, you would have defined the interface as shown below.

[OperationContract]
double AddOperation(double a, double b)

But in order to do the same thing in WCF LOB adapter, you would have done something like this

//Param 1
OperationParameter n1 = new OperationParameter("a"
                                        , OperationParameterDirection.In
                                        , QualifiedType.DoubleType, false);
n1.IsOptional = false;
opMetadata.Parameters.Add(n1);

//Param 2
OperationParameter n2 = new OperationParameter("b"
                                        , OperationParameterDirection.In
                                        , QualifiedType.DoubleType, false);
n2.IsOptional = false;
opMetadata.Parameters.Add(n2);

//Result
opMetadata.OperationResult = new OperationResult(QualifiedType.DoubleType, false);
break;

The reason for the complexity is mainly due the dynamic nature of the WCF LOB adapters, often times you’ll be constructing the operation request and response types based on your underlying LOB applications requirement.

WCF LOB Adapter SDK comes with rich set of Metadata object model to cater for various situations. That includes

  • Operation/Type Metadata Object Model is used for contract generation
  • ParameterizedOperationMetadata class can be used for most common operation representations (as shown above)
  • StructuredTypeMetadata can be used for most common types representations
  • Metadata object model is extensible by allowing the adapter developer to provide own XML Schema representations for its members using ExportXmlSchema methods.

The last option ExportXmlSchema is the one you’ll use when the underlying LOB systems already defined XSD schemas and you just want to reuse it. Example

[OperationContract]

CustomerResponse GetCustomer(RetailCustomer customer)

The EchoAdapter sample and some of the great articles from Sonu Arora’s WCF LOB adapter series all explain about the simple scenario where a types is self contained within a single XSD file. But in reality you’ll be using multiple XSD files together either with xsd:include or xsd:import. I can see an open thread here at msdn forum without a resolution.

When you try to deal with schemas that include other schemas, you’ll typically see the following error

Error while retrieving or generating the WSDL. Adapter message: The ‘urn:schemas-XXXXX:b2b:WorkItemNo’ element is not declared.

The solution to that problem is quite straight forward. In the ExportXmlSchema method, you loop through the included schemas before doing your regular one. In the below example the code in bold is a common schema, and the code below that is what you’ll normally have.

public override void ExportXmlSchema(XmlSchemaExportContext schemaExportContext, MetadataLookup metadataLookup, TimeSpan timeout)
{
    if (schemaExportContext == null)
    {
        throw new AdapterException("Schema export context is null.");
    }

    //Read Common Schemas

    Stream commonXsdFile = Assembly.GetExecutingAssembly().GetManifestResourceStream(COMMOM_METADATA_FILE_NAME);
    using (XmlReader reader = XmlReader.Create(commonXsdFile))
    {
        XmlSchema schema = XmlSchema.Read(reader, null);
        if (!IsComplexTypeAlreadyDefined(schemaExportContext.SchemaSet, schema))
        {
            schemaExportContext.SchemaSet.Add(schema);
            if (!schemaExportContext.NamespacePrefixSet.ContainsKey(this.TypeNamespace))
            {
                schemaExportContext.NamespacePrefixSet.Add(this.TypeNamespace
                    , getUniqueNamespacePrefix(schemaExportContext, 0));
            }
        }
    }


    // Read in XML Schema file or create XmlSchema object yourself
    Stream predefinedXsdFile = Assembly.GetExecutingAssembly().GetManifestResourceStream(CONST_METADATA_FILE_NAME);
    using (XmlReader reader = XmlReader.Create(predefinedXsdFile))
    {
        XmlSchema schema = XmlSchema.Read(reader, null);
        if (!IsComplexTypeAlreadyDefined(schemaExportContext.SchemaSet, schema))
        {
            schemaExportContext.SchemaSet.Add(schema);
            if (!schemaExportContext.NamespacePrefixSet.ContainsKey(this.TypeNamespace))
            {
                schemaExportContext.NamespacePrefixSet.Add(this.TypeNamespace
                    , getUniqueNamespacePrefix(schemaExportContext, 0));
            }
        }
        //reader.Close();
    }
}

Nandri

Saravana Kumar

Author: Saravana Kumar

Saravana Kumar is the Founder and CTO of BizTalk360, an enterprise software that acts as an all-in-one solution for better administration, operation, support and monitoring of Microsoft BizTalk Server environments.

One Platform Operations, Monitoring and Analytics Software
BizTalk360

microsoft biztalk

Learn more

Over 500 customers across 30+ countries depend on BizTalk360

ServiceBus360

Azure service bus

Learn more

Start managing your Azure Service Bus namespaces in minutes

One Platform - Operations, Monitoring and Analytics Software
BizTalk360

microsoft biztalk

Learn more

Over 500 customers across 30+ countries depend on BizTalk360

One Platform - Operations, Monitoring and Analytics Software
ServiceBus360

Azure service bus

Learn more

Start managing your Azure Service Bus namespaces in minutes

Back to Top