using System;
using System.Collections.Generic;
using System.Text;
using System.XML.Serialization.Advanced;
using System.Collections;
using System.XML.Schema;
using System.XML.Serialization;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.XML;
using System.Data;
namespace Xrinehart.Tools.WebService.SchemaImporter

{
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;
}
}

}
<sectionGroup name="system.XML.serialization" type="System.XML.Serialization.Configuration.SerializationSectionGroup, System.XML, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="schemaImporterExtensions" type="System.XML.Serialization.Configuration.SchemaImporterExtensionsSection, System.XML, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<section name="dateTimeSerialization" type="System.XML.Serialization.Configuration.DateTimeSerializationSection, System.XML, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<section name="XMLSerializer" type="System.XML.Serialization.Configuration.XMLSerializerSection, System.XML, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
<system.XML.serialization>
<schemaImporterExtensions>
<add name="dataTableSchemaImporterExtension" type="Xrinehart.Tools.WebService.SchemaImporter.DataTableSchemaImporterExtension, Xrinehart.Tools.WebService.SchemaImporter,Version=1.0.0.0,Culture=neutral,PublicKeyToken=5a627ce15fb94702" />
</schemaImporterExtensions>
</system.XML.serialization>
完成以上的步骤后,再编译WebService,重新引用(或者更新Web引用),就可以正确的识别DataTable类型了。
其实DataTable只实现了序列化,但WebService并不能自己反序列化为可识别的格式,所以需要自己手动增加。由此可以衍生为各种业务实体BussinessEntity类对象也可以通过以上方式实现直接传递。
希望对大家有所帮助。