在2.0正式版发布之前,就满天的看到关于DataTable支持序列化的新特性宣传,满以为从此以后使用DataTable就和DataSet一样方便了,结果在应用项目的时候才发现并非那么回事。
/?"
DataTable是支持序列化了,但是微软并没有把他做的特别方便,还需要我们自己来做一些工作之后才能够在WebService里面传递DataTable,否则在引用DataTable的时候会发现DataTable变成了一个什么Proxy类型。
首先编写类DataTableSchemaImporterExtension,代码如下:
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;
![]()
}
![]()
}
![]()
![]()
}
为此类添加进一个项目中,并将此项目进行强命名后编译。
然后,把该Assembly程序集加入到GAC中。
最后修改本机的machine.config,代码如下:
<
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
>
DataTable是支持序列化了,但是微软并没有把他做的特别方便,还需要我们自己来做一些工作之后才能够在WebService里面传递DataTable,否则在引用DataTable的时候会发现DataTable变成了一个什么Proxy类型。
首先编写类DataTableSchemaImporterExtension,代码如下:
然后,把该Assembly程序集加入到GAC中。
最后修改本机的machine.config,代码如下:
完成以上的步骤后,再编译WebService,重新引用(或者更新Web引用),就可以正确的识别DataTable类型了。
其实DataTable只实现了序列化,但WebService并不能自己反序列化为可识别的格式,所以需要自己手动增加。由此可以衍生为各种业务实体BussinessEntity类对象也可以通过以上方式实现直接传递。
希望对大家有所帮助。