Web Service returning Datatable question

Is it possible to return a datatable that is not strongly typed from a web service using 2.0 When I try it the return type of the method in my proxy class is MyWebMethodResponseMyWebMethod­NameResult. I have read that in VS 2.0 you can return standalone datatables from web services.


Answer this question

Web Service returning Datatable question

  • ghostsoft

    DataTable implements IXmlSerializable, and the schema for the DataTable is unique enough allowing wsdl.exe to take advantage of the new feature (SchemaImporterExtension) to generate DataTable on the client.

    Here is what you need to do

    1. Create SchemaImporterExtension that will recognize the DataSetSchema:

    The V2 Framework uses anonymous complexType for DataSet schema:

    <s:complexType>

    <s:sequence>

    <s:any minOccurs="0" maxOccurs="unbounded" namespace="http://www.w3.org/2001/XMLSchema" processContents="lax" />

    <s:any minOccurs="1" namespace="urn:schemas-microsoft-com:xml-diffgram-v1" processContents="lax" />

    </s:sequence>

    </s:complexType>

    You need to write the extension that maps the above schema pattern to a DataTable type:

    class DataTableSchemaImporterExtension : SchemaImporterExtension

    {

    // DataTableSchemaImporterExtension is used for WebServices, it is used to recognize the schema for DataTable within wsdl

    Hashtable importedTypes = new Hashtable();

    public override string ImportSchemaType(string name, string schemaNamespace, XmlSchemaObject context, XmlSchemas schemas, XmlSchemaImporter importer, CodeCompileUnit compileUnit, CodeNamespace mainNamespace, CodeGenerationOptions options, CodeDomProvider codeProvider)

    {

    IList values = schemas.GetSchemas(schemaNamespace);

    if (values.Count != 1)

    {

    return null;

    }

    XmlSchema schema = values[0] as XmlSchema;

    if (schema == null)

    return null;

    XmlSchemaType type = (XmlSchemaType)schema.SchemaTypes[new XmlQualifiedName(name, schemaNamespace)];

    return ImportSchemaType(type, context, schemas, importer, compileUnit, mainNamespace, options, codeProvider);

    }

    public override string ImportSchemaType(XmlSchemaType type, XmlSchemaObject context, XmlSchemas schemas, XmlSchemaImporter importer, CodeCompileUnit compileUnit, CodeNamespace mainNamespace, CodeGenerationOptions options, CodeDomProvider codeProvider)

    {

    if (type == null)

    {

    return null;

    }

    if (importedTypes[type] != null)

    {

    mainNamespace.Imports.Add(new CodeNamespaceImport(typeof(DataSet).Namespace));

    compileUnit.ReferencedAssemblies.Add("System.Data.dll");

    return (string)importedTypes[type];

    }

    if (!(context is XmlSchemaElement))

    return null;

    if (type is XmlSchemaComplexType)

    {

    XmlSchemaComplexType ct = (XmlSchemaComplexType)type;

    if (ct.Particle is XmlSchemaSequence)

    {

    XmlSchemaObjectCollection items = ((XmlSchemaSequence)ct.Particle).Items;

    if (items.Count == 2 && items[0] is XmlSchemaAny && items[1] is XmlSchemaAny)

    {

    XmlSchemaAny any0 = (XmlSchemaAny)items[0];

    XmlSchemaAny any1 = (XmlSchemaAny)items[1];

    if (any0.Namespace == XmlSchema.Namespace && any1.Namespace == "urn:schemas-microsoft-com:xml-diffgram-v1")

    {

    string typeName = typeof(DataTable).FullName;

    importedTypes.Add(type, typeName);

    mainNamespace.Imports.Add(new CodeNamespaceImport(typeof(DataTable).Namespace));

    compileUnit.ReferencedAssemblies.Add("System.Data.dll");

    return typeName;

    }

    }

    }

    }

    return null;

    }

    }

    1. compile and GAC the SchemaImporterExtension
    2. add it to the existent extensions in machine.config, ysing fully-qualified assembly name


    <system.xml.serialization>

    <schemaImporterExtensions>

    <add name="DataTableSchemaImporterExtension" type="DataTableSchemaImporterExtension,... </schemaImporterExtensions>

    </system.xml.serialization>

    Thanks,

    Elena Kharitidi


  • mehim

    I'm having the same problem. I'm not explicitly using the wsdl tool, but it seems to be the right version.

    ' <auto-generated>
    '   This code was generated by a tool.
    '   Runtime Version:2.0.50727.42
    '' </auto-generated>

    I've got both .net 1.1 and 2.0 installed on this machine though..
    The datatable i'm returning is not strongly typed.

    I'm gonna bypass it for now by using a dataset instead, but I don't want to leave it like that. Any ideas

    /Daniel

     


  • bowie


  • SamProsser

    I have returned both strong and not strongly typed datatables from webmethods in ASP.Net 2.0.  You must generate the proxy class using the 2.0 version of the WSDL tool else you will get the odd named returned types that you are seeing.
    (Since ASP.Net 1.1 didnt support it)

    You will notice that the datatable is actually wrapped inside a generic dataset in the returning soap message.

  • Web Service returning Datatable question