C# 从ReST调用返回ADODB.Recordset作为ADODB.Recordset

C# 从ReST调用返回ADODB.Recordset作为ADODB.Recordset,c#,rest,persistence,ado,recordset,C#,Rest,Persistence,Ado,Recordset,我正试图以渐进的方式将遗留应用程序引入当前的技术中。我在服务器上使用ADO有一个C++ COM+库。VB6应用程序正在使用基于上述库的COM+对象中的记录集。我想删除COM+层,因此我创建了一个具有ASP.NET web API项目类型的ReST web服务。使用C#中内置的HTTP结果(即Ok和BadRequest),我似乎无法像返回其他数据类型那样返回记录集。我一直试图通过记录集持久性来实现这一点。我将记录集保存为流,如下所示: ADODB._Recordset rs; string rsS

我正试图以渐进的方式将遗留应用程序引入当前的技术中。我在服务器上使用ADO有一个C++ COM+库。VB6应用程序正在使用基于上述库的COM+对象中的记录集。我想删除COM+层,因此我创建了一个具有ASP.NET web API项目类型的ReST web服务。使用C#中内置的HTTP结果(即Ok和BadRequest),我似乎无法像返回其他数据类型那样返回记录集。我一直试图通过记录集持久性来实现这一点。我将记录集保存为流,如下所示:

ADODB._Recordset rs;
string rsString;
SomeLibrary sl = new SomeLibrary();
rs = (ADODB._Recordset)sl.SomeMethod();
Stream stream = new Stream();
rs.Save(stream, PersistFormatEnum.adPersistXML);
rs.Close();
rsString = stream.ReadText();
return Ok(rsString);
C#客户端尝试获取此持久化的ADO记录集并重新创建对象,如下所示:

_Recordset ret = null;
string strResponse = string.Empty;
Does things to call out to the ReST web service...
ret = new Recordset();
byte[] rsByteArray = Encoding.ASCII.GetBytes(strResponse);
ret.Open(new MemoryStream(rsByteArray));
在最后一行,我得到以下错误:

参数类型错误、超出可接受范围或相互冲突

持久化的XML如下所示:

<xml xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882' xmlns:dt='uuid:C2F41010-65B3-11d1-A29F-00AA00C14882' xmlns:rs='urn:schemas-microsoft-com:rowset' xmlns:z='#RowsetSchema'>
<s:Schema id='RowsetSchema'>
    <s:ElementType name='row' content='eltOnly' rs:CommandTimeout='600' rs:ReshapeName='DSRowset1'>
        <s:AttributeType name='ID' rs:number='1'>
            <s:datatype dt:type='int' dt:maxLength='4' rs:precision='10' rs:fixedlength='true' rs:maybenull='false'/>
        </s:AttributeType>
        <s:AttributeType name='c1' rs:name='Some Date' rs:number='2' rs:nullable='true'>
            <s:datatype dt:type='dateTime' rs:dbtype='timestamp' dt:maxLength='16' rs:scale='3' rs:precision='23' rs:fixedlength='true'/>
        </s:AttributeType>
        <s:AttributeType name='Status' rs:number='3' rs:nullable='true'>
            <s:datatype dt:type='ui1' dt:maxLength='1' rs:precision='3' rs:fixedlength='true'/>
        </s:AttributeType>
        <s:AttributeType name='c3' rs:name='File Name' rs:number='4' rs:nullable='true'>
            <s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='2000'/>
        </s:AttributeType>
        <s:AttributeType name='c4' rs:name='User ID' rs:number='5'>
            <s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='32' rs:maybenull='false'/>
        </s:AttributeType>
        <s:extends type='rs:rowbase'/>
    </s:ElementType>
</s:Schema>
<rs:data>
<z:row ID='3319' c1='2017-06-26T08:14:46' Status='2'
     c3='somefile.XML' c4='domain\\user'/>
</rs:data>
</xml>
ADODB.Stream stream = new ADODB.Stream();
rs.Save(stream, PersistFormatEnum.adPersistXML);
rs.Close();
rsString = stream.ReadText();
return Ok(rsString);
_Recordset ret = null;
string strResponse = string.Empty;
Does things to call out to the ReST web service...
if (!string.IsNullOrEmpty(strResponse))
{
    strResponse = strResponse.Replace("\\t", "    ").Replace("\\r\\n", " ").Replace("\"", "");
    ret = new Recordset();
    ADODB.Stream stream = new ADODB.Stream();
    stream.Open();
    stream.WriteText(strResponse);
    stream.Position = 0;
    ret.Open(stream);
}

return ret;
并向客户发送以下信息:

<xml xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882' xmlns:dt='uuid:C2F41010-65B3-11d1-A29F-00AA00C14882' xmlns:rs='urn:schemas-microsoft-com:rowset' xmlns:z='#RowsetSchema'>
<s:Schema id='RowsetSchema'>
    <s:ElementType name='row' content='eltOnly' rs:CommandTimeout='600' rs:ReshapeName='DSRowset1'>
        <s:AttributeType name='ID' rs:number='1'>
            <s:datatype dt:type='int' dt:maxLength='4' rs:precision='10' rs:fixedlength='true' rs:maybenull='false'/>
        </s:AttributeType>
        <s:AttributeType name='c1' rs:name='Some Date' rs:number='2' rs:nullable='true'>
            <s:datatype dt:type='dateTime' rs:dbtype='timestamp' dt:maxLength='16' rs:scale='3' rs:precision='23' rs:fixedlength='true'/>
        </s:AttributeType>
        <s:AttributeType name='Status' rs:number='3' rs:nullable='true'>
            <s:datatype dt:type='ui1' dt:maxLength='1' rs:precision='3' rs:fixedlength='true'/>
        </s:AttributeType>
        <s:AttributeType name='c3' rs:name='File Name' rs:number='4' rs:nullable='true'>
            <s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='2000'/>
        </s:AttributeType>
        <s:AttributeType name='c4' rs:name='User ID' rs:number='5'>
            <s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='32' rs:maybenull='false'/>
        </s:AttributeType>
        <s:extends type='rs:rowbase'/>
    </s:ElementType>
</s:Schema>
<rs:data>
<z:row ID='3319' c1='2017-06-26T08:14:46' Status='2'
     c3='somefile.XML' c4='domain\\user'/>
</rs:data>
</xml>
ADODB.Stream stream = new ADODB.Stream();
rs.Save(stream, PersistFormatEnum.adPersistXML);
rs.Close();
rsString = stream.ReadText();
return Ok(rsString);
_Recordset ret = null;
string strResponse = string.Empty;
Does things to call out to the ReST web service...
if (!string.IsNullOrEmpty(strResponse))
{
    strResponse = strResponse.Replace("\\t", "    ").Replace("\\r\\n", " ").Replace("\"", "");
    ret = new Recordset();
    ADODB.Stream stream = new ADODB.Stream();
    stream.Open();
    stream.WriteText(strResponse);
    stream.Position = 0;
    ret.Open(stream);
}

return ret;

VB6模块现在可以像从COM+对象接收数据一样接受数据。我希望这能帮助其他需要以廉价增量更新技术的人。

您需要在recordset open方法中传递ADODB.Stream对象,如:

ADODB.Stream strm = new ADODB.Stream();
strm.Open();
strm.LoadFromFile(@"D:\XMLRecordset.xml"); 
Recordset rs = new Recordset();
rs.Open(strm);
但是上面提到的(使用流对象)并不能很好地工作——不知道为什么。但您可以使用文件路径打开记录集,其工作方式如下:

Recordset rs = new Recordset();
rs.Open(@"D:\XMLRecordset.xml");

另外,如果您不想处理记录集,您可以从web api传递对象列表,并在VB6应用程序中解析JSON字符串以获得结果(请在此处检查Ben的答案)

必须在客户端编写XML文件既没有性能,也不可取。是的,我用JSON库完成了这项工作。它需要在VB6应用程序上进行工作,这激发了pushback,因为它所代表的工作量很大。作为一个更新,我尝试将streams更改为ADODB.Stream对象。它向前推进了一点,所以我希望这将是公认的答案。但我不知道为什么现在出错与这个答案的问题有关。我会在找到答案后进行更新。这让我找到了正确的方向,所以我将把它标记为答案,尽管它不完整。很高兴知道它帮助您解决了问题:)是的。非常感谢你。