2017-10-18 59 views
0

Je tente de prendre de façon incrémentielle une application héritée dans les technologies actuelles. J'ai une bibliothèque COM + C++ utilisant ADO sur un serveur. Une application VB6 utilise le jeu d'enregistrements à partir d'un objet COM + basé sur la bibliothèque mentionnée ci-dessus. Je souhaite supprimer la couche COM +, j'ai donc créé un service Web ReST avec le type de projet ASP.NET Web API. Je n'arrive pas à retourner un jeu d'enregistrements comme d'autres types de données utilisant les résultats HTTP intégrés dans C# (c'est-à-dire Ok et BadRequest). J'ai essayé d'accomplir ceci par la persistance de Recordset. Je sauve le jeu d'enregistrements en tant que flux comme suit:Retour ADODB.Recordset à partir de l'appel ReST en tant que ADODB.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); 

Le client C# essaie de prendre ce persista ADO Recordset et recréer l'objet comme ceci:

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

Sur la dernière ligne, je reçois l'erreur suivante:

Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another.

le XML persistant se présente comme suit:

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

L'objectif est d'avoir un jeu d'enregistrements ADO à renvoyer à l'application VB6 afin qu'il ne sache jamais que l'implémentation a changé autrement que peut-être une nouvelle référence à la nouvelle bibliothèque C# au lieu de la bibliothèque COM +.

Y at-il un bogue dans ce que j'ai écrit ou est-ce simplement impossible? Si ce n'est pas possible, est-ce que quelqu'un sait un chemin différent que je peux prendre pour essayer d'accomplir cette tâche?

EDIT:
La réponse à cette question a été très utile. Quand je l'ai finalement obtenu de travail, je l'ai changé le serveur à ce qui suit:

ADODB.Stream stream = new ADODB.Stream(); 
rs.Save(stream, PersistFormatEnum.adPersistXML); 
rs.Close(); 
rsString = stream.ReadText(); 
return Ok(rsString); 

Et le client à ce qui suit:

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

Le module VB6 peut désormais accepter des données comme si elle a reçu de la Objet COM + J'espère que cela aidera quelqu'un d'autre qui a besoin de mettre à jour leur technologie par incréments bon marché.

Répondre

0

Vous devez passer l'objet ADODB.Stream dans recordset méthode ouverte comme:

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

Mais au-dessus (en utilisant l'objet flux) ne fonctionne pas aussi bien - ne sais pas pourquoi. Mais vous pouvez utiliser le chemin du fichier pour ouvrir recordset et fonctionnera comme:

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

Aussi, si vous ne voulez pas traiter recordset, vous pouvez passer la liste des objets de api web et en application VB6 analyser la chaîne JSON pour obtenir des résultats (vérifier la réponse de Ben ici Is There a JSON Parser for VB6/VBA?)

+0

Avoir à écrire des fichiers XML sur le côté client n'est pas performant ni souhaitable. Oui, je l'ai fait avec une bibliothèque JSON. Il a fallu travailler sur l'application VB6 qui a inspiré le refoulement en raison de la quantité de travail représentée. – BillyD

+0

En tant que mise à jour, j'essaie de simplement changer les flux en objets ADODB.Stream. Cela avance un peu, alors je m'attends à ce que ce soit la réponse acceptée. Mais je ne sais pas si c'est une erreur d'avoir un problème avec cette réponse. Je vais mettre à jour au fur et à mesure. – BillyD

+0

Cela m'a envoyé dans la bonne direction, donc je vais le signaler comme la réponse, même si elle n'est pas complète. – BillyD