从ADST调用ADODB.Recordset返回ADODB.Recordset

时间:2017-10-18 21:06:18

标签: c# rest persistence ado recordset

我正在尝试逐步将遗留应用程序转换为当前技术。我有一个在服务器上使用ADO的C ++ COM +库。 VB6应用程序正在使用基于上述库的COM +对象的Recordset。我想删除COM +层,因此我使用ASP.NET Web API项目类型创建了一个ReST Web服务。我似乎无法像使用C#内置的HTTP结果(即Ok和BadRequest)那样返回Recordset。我一直试图通过Recordset持久性来实现这一目标。我将Recordset保存为流,如下所示:

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并重新创建对象,如下所示:

_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>

目标是让一个ADO Recordset发送回VB6应用程序,这样它就不会知道实现发生了变化,而不是对新C#库而不是COM +库的新引用。

我写过的内容是否有错误,或者这是不可能的?如果不可能,有没有人知道我可以采取不同的路径来尝试完成这项任务?

编辑:
这个问题的答案肯定是有帮助的。当我最终使它工作时,我将服务器更改为以下内容:

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 +对象接收数据一样。我希望这可以帮助需要以便宜的增量更新技术的其他人。

1 个答案:

答案 0 :(得分:0)

您需要在记录集打开方法中传递ADODB.Stream对象,如:

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

但上面(使用Stream对象)效果不佳 - 不知道为什么。但您可以使用文件路径打开记录集,其工作方式如下:

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

此外,如果你不想处理记录集,你可以从web api传递对象列表,并在VB6应用程序中解析JSON字符串以获得结果(查看Ben的回答Is There a JSON Parser for VB6 / VBA?