Published on : Sep 16, 2011
Category : General
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