ASP.NET 2.0 雖宣稱 DataTable 支援序列化,但 Web Service 專案加入 Web 參考時,DataTable 會被代理為非強型別的 Proxy 類別,無法直接使用。需自行實作 SchemaImporterExtension 攔截 WSDL 匯入過程,將 DataTable 結構描述映射回 System.Data.DataTable 型別。
using System.Xml.Schema;
using System.Xml.Serialization;
using System.Xml.Serialization.Advanced;
using System.CodeDom;
using System.Data;
namespace Xrinehart.Tools.WebService.SchemaImporter {
public class DataTableSchemaImporterExtension : SchemaImporterExtension {
private Hashtable importedTypes = new Hashtable();
public override string ImportSchemaType(string name, string ns, XmlSchemaObject context,
XmlSchemas schemas, XmlSchemaImporter importer, CodeCompileUnit compileUnit,
CodeNamespace mainNamespace, CodeGenerationOptions options, CodeDomProvider provider) {
// 取得目標 Schema 並委派給多載方法
}
public override string ImportSchemaType(XmlSchemaType type, XmlSchemaObject context,
XmlSchemas schemas, XmlSchemaImporter importer, CodeCompileUnit compileUnit,
CodeNamespace mainNamespace, CodeGenerationOptions options, CodeDomProvider provider) {
// 核心判斷邏輯:偵測 DataTable 特有的 DiffGram 結構
if (type is XmlSchemaComplexType ct && ct.Particle is XmlSchemaSequence seq) {
var items = seq.Items;
if (items.Count == 2 && items[0] is XmlSchemaAny any0 && items[1] is XmlSchemaAny any1) {
if (any0.Namespace == XmlSchema.Namespace &&
any1.Namespace == "urn:schemas-microsoft-com:xml-diffgram-v1") {
// 確認為 DataTable 結構,註冊型別映射
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;
}
}
}
Bin 目錄或 GAC。web.config 中註冊擴充:
<configuration>
<system.xml.serialization>
<schemaImporterExtensions>
<add name="DataTableImporter"
type="Xrinehart.Tools.WebService.SchemaImporter.DataTableSchemaImporterExtension, YourAssembly" />
</schemaImporterExtensions>
</system.xml.serialization>
</configuration>
此方案適用於 ASP.NET 2.0 ASMX Web Service;若使用 WCF,建議直接使用 DataTable 作為資料合約或改用 List<T>、POCO 實體傳輸,避免序列化複雜度。