我正在尝试逐步将遗留应用程序转换为当前技术。我有一个在服务器上使用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 +对象接收数据一样。我希望这可以帮助需要以便宜的增量更新技术的其他人。
答案 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?)