在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>
  完成以上的步驟后,再編譯webservice,重新引用(或者更新web引用),就可以正確的識別datatable類型了。
  其實datatable只實現了序列化,但webservice并不能自己反序列化為可識別的格式,所以需要自己手動增加。由此可以衍生為各種業務實體bussinessentity類對象也可以通過以上方式實現直接傳遞。
希望對大家有所幫助。
新聞熱點
疑難解答
圖片精選