Return ADODB.Recordset 来自 ReST Call as ADODB.Recordset
Return ADODB.Recordset from ReST Call as ADODB.Recordset
我正在尝试逐步将遗留应用程序纳入当前技术。我有一个在服务器上使用 ADO 的 C++ COM+ 库。 VB6 应用程序正在使用来自基于上述库的 COM+ 对象的 Recordset。我想删除 COM+ 层,所以我创建了一个 ASP.NET Web API 项目类型的 ReST Web 服务。我似乎无法 return Recordset,就像我使用 C# 中内置的 HTTP 结果(即 Ok 和 BadRequest)处理其他数据类型一样。我一直在尝试通过 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 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));
在最后一行,我收到以下错误:
Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another.
持久化的 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>
objective 是要有一个 ADO 记录集发送回 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+ 对象接收数据一样接受数据。我希望这对需要以低廉的增量更新技术的其他人有所帮助。
您需要在记录集打开方法中传递 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");
此外,如果您不想处理记录集,您可以从网络 api 传递对象列表,并在 VB6 应用程序中解析 JSON 字符串以获得结果(查看 Ben 的回答这里 Is There a JSON Parser for VB6 / VBA?)
我正在尝试逐步将遗留应用程序纳入当前技术。我有一个在服务器上使用 ADO 的 C++ COM+ 库。 VB6 应用程序正在使用来自基于上述库的 COM+ 对象的 Recordset。我想删除 COM+ 层,所以我创建了一个 ASP.NET Web API 项目类型的 ReST Web 服务。我似乎无法 return Recordset,就像我使用 C# 中内置的 HTTP 结果(即 Ok 和 BadRequest)处理其他数据类型一样。我一直在尝试通过 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 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));
在最后一行,我收到以下错误:
Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another.
持久化的 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>
objective 是要有一个 ADO 记录集发送回 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+ 对象接收数据一样接受数据。我希望这对需要以低廉的增量更新技术的其他人有所帮助。
您需要在记录集打开方法中传递 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");
此外,如果您不想处理记录集,您可以从网络 api 传递对象列表,并在 VB6 应用程序中解析 JSON 字符串以获得结果(查看 Ben 的回答这里 Is There a JSON Parser for VB6 / VBA?)