Question

Actuellement, je lance une (ancienne) page Web ASP classique avec un objet recordset utilisé directement dans la mauvaise vieille mode de code spagethi.

Je pense implémenter une couche de données dans asp.net en tant que service Web pour améliorer la gérabilité.Il s'agit également d'une première étape vers la mise à niveau du site Web vers asp.net.Le site lui-même reste ASP pour le moment...

Quelqu'un peut-il recommander un bon moyen de remplacer le type d'objet Recordset par un type compatible avec le service Web (comme un tableau ou quelque chose du genre) ?Par quoi dois-je remplacer ci-dessous ? :

set objRS = oConn.execute(SQL)
while not objRS.eof
   ...
   name = Cstr(objRS(1))
   ...
wend

et plusieurs jeux d'enregistrements peuvent également être remplacés par ?Je parle :

 set objRS = objRs.nextRecordset 

Quelqu'un a vécu ça et peut me recommander ?

@AdditionalInfo - vous l'avez demandé :-)

Permettez-moi de commencer par le début.La situation actuelle est:J'ai un ancien site Web ASP avec un contenu hiérarchique classique (en-tête, section, sous-section, contenu) extrait de la base de données via des procédures stockées et les pages de contenu sont également dans la base de données (un lien vers un fichier HTML).

Le problème, c'est que le code ASP est partout réparti sur de nombreux fichiers .asp qui effectuent tous leurs propres connexions à la base de données, lisent et écrivent (vous devez vous inscrire pour le contenu).Récemment, nous avons eu des problèmes avec les attaques par injection SQL, j'ai donc été appelé pour les résoudre.

je pourrait allez changer toutes les pages .asp pour empêcher l'injection SQL mais ce serait de la folie.J'ai donc pensé créer une couche de données - toutes les pages utilisant cette couche pour accéder à la base de données.Une fois placé pour corriger et mettre à jour le code d'accès à la base de données.

En arrivant à cette décision, j'ai pensé que la mise à niveau d'asp.net n'était pas loin, pourquoi ne pas commencer à utiliser asp.net pour la couche de données ?De cette façon, il pourra être réutilisé lors de la mise à niveau du site.

Cela m'amène aux questions ci-dessus !

Était-ce utile?

La solution

Si vous souhaitez vous en tenir à l'ASP classique, je vous suggère de créer un objet de gestion de base de données via les classes ASP, puis d'utiliser simplement cet objet pour effectuer vos créations de jeux d'enregistrements.Cela centraliserait le code de gestion de votre base de données et ferait en sorte que vous n'ayez à gérer que les attaques par injection SQL dans un seul emplacement.

Un exemple simple.

Class clsDatabase

    Private Sub Class_Initialize()
        If Session("Debug") Then Response.Write "Database Initialized<br />"
    End Sub

    Private Sub Class_Terminate()
        If Session("Debug") Then Response.Write "Database Terminated<br />"
    End Sub

    Public Function Run(SQL)
        Set RS = CreateObject("ADODB.Recordset")
        RS.CursorLocation = adUseClient
        RS.Open SQLValidate(SQL), Application("Data"), adOpenKeyset, adLockReadOnly, adCmdText
        Set Run = RS
        Set RS = nothing
    End Function

    Public Function SQLValidate(SQL)
        SQLValidate = SQL
        SQLValidate = Replace(SQLValidate, "--", "", 1, -1, 1)
        SQLValidate = Replace(SQLValidate, ";", "", 1, -1, 1)
        SQLValidate = Replace(SQLValidate, "SP_", "", 1, -1, 1)
        SQLValidate = Replace(SQLValidate, "@@", "", 1, -1, 1)
        SQLValidate = Replace(SQLValidate, " DECLARE", "", 1, -1, 1)
        SQLValidate = Replace(SQLValidate, "EXEC", "", 1, -1, 1)
        SQLValidate = Replace(SQLValidate, " DROP", "", 1, -1, 1)
        SQLValidate = Replace(SQLValidate, " CREATE", "", 1, -1, 1)
        SQLValidate = Replace(SQLValidate, " GRANT", "", 1, -1, 1)
        SQLValidate = Replace(SQLValidate, " XP_", "", 1, -1, 1)
        SQLValidate = Replace(SQLValidate, "CHAR(124)", "", 1, -1, 1)
    End Function
End Class

Ensuite, pour l'utiliser, vous devez modifier vos appels en :

Set oData = new clsDatabase
Set Recordset = oData.Run("SELECT field FROM table WHERE something = another")
Set oData = nothing

Bien sûr, vous pouvez étendre la classe de base pour gérer des procédures stockées paramétrées ou autre et plus de validations, etc.

Autres conseils

Tout d’abord mon conseil préféré de cette semaine :ne traitez pas votre service Web comme s'il s'agissait d'un objet local, sinon vous allez payer un prix de performance très élevé.Essentiellement, ne faites pas des choses comme ça dans votre application Web :

MyDataWebService ws = new MyDataWebService();
foreach(DataItem item in myData)
{
    ws.Insert(item);
}

Vous devriez toujours préférer minimiser les appels à votre service Web (et SQL) :

MyDataWebService ws = new MyDataWebService();
ws.Insert(myData); // Let the web service process the whole set at once.

Désormais, en ce qui concerne le type de données à utiliser pour vos appels de service Web, vous avez essentiellement deux choix :

  • Base de données
  • Tout le reste (Array)

La plupart des collections renvoyées par un service Web (comme un List<MyData>) sont en fait converties en Array lors de l'invocation du service Web.N'oubliez pas que les services Web ne renvoient pas d'objets (données + comportement) mais simplement des structures de données (ou une séquence de).Par conséquent, il y a peu de distinction entre une liste et un tableau.

Les DataSets sont des classes plus complexes ;ils utilisent leur propre sérialiseur personnalisé et sont quasiment entièrement recréés dans l'application appelante.Il y a un coût en termes de performances à payer pour utiliser des DataSets comme celui-ci, donc je ne le recommande généralement pas pour la plupart des scénarios.Utiliser des tableaux pour transmettre des données dans les deux sens a tendance à être plus efficace et, franchement, c'est plus facile à faire.

Votre cas est un peu différent ;étant donné que vous convertissez un site existant qui utilise déjà ADO, un DataSet ADO.NET pourrait être votre meilleur chemin de mise à niveau.ADO.NET et ADO sont suffisamment similaires pour qu'une mise à jour directe puisse être plus facile de cette façon.Cela dépend en quelque sorte de la manière dont votre site Web est construit.

Pour la dernière partie de votre question, les DataSets prennent en charge plusieurs jeux d'enregistrements similaires au Recordset d'ADO.Ils sont appelés DataTables.Chaque DataSet possède au moins un DataTable et vous pouvez les lire dans n'importe quel ordre.

Bonne chance.

Je suggère d'utiliser la classe XmlHttp dans votre code ASP.

En supposant que vous disposez d'un service Web ASMX similaire à celui-ci, dans MyService.asmx :

[WebMethod]
public string HelloWorld()
{
  return "Hello World";
}

Vous pourriez l'appeler en ASP comme ceci :

Dim xhr

Set xhr = server.CreateObject("MSXML2.XMLHTTP")

xhr.Open "POST", "/MyService.asmx/HelloWorld", false
xhr.SetRequestHeader "content-type", "application/x-www-form-urlencoded"
xhr.Send

Response.Write(xhr.ResponseText)

ResponseText serait une réponse XML de :

<string>Hello World</string>

En supposant que votre service ait renvoyé une collection de données, vous pouvez la parcourir à l'aide de XPath ou de toute autre technique/bibliothèque de traitement XML.

Rechercher Google sur MSXML2 répondra probablement à toutes vos questions spécifiques, car il est spécifique à ASP classic.

Au lieu de penser par couches, pourquoi ne pas essayer de prendre des tranches verticales dans l'application et de les convertir en .net.De cette façon, vous obtiendrez des fonctionnalités entières codées en .net au lieu de parties disjointes.Quelle est la valeur commerciale du remplacement d’un code fonctionnant parfaitement sans améliorer l’expérience utilisateur ni ajouter de fonctionnalités ?

Vous pouvez également envisager le compromis en termes de performances que vous allez abandonner avec un service Web par rapport aux appels directs.Les services Web constituent une bonne solution au problème de plusieurs applications/équipes disjointes accédant à un schéma commun ;ils ne rendent pas une application isolée plus facile à maintenir, mais seulement plus lente et plus complexe.

Une autre alternative consiste à utiliser COM Interop pour créer un assembly dans .NET pouvant être appelé à partir d’ASP classique.

Pour créer un assembly COM Interop à partir de Visual Studio (par ex.Microsoft Visual C# 2005 Édition Express) :

  • Créer un nouveau projet de bibliothèque de classes
  • Ouvrez les propriétés du projet

    • Sous Application, sélectionnez Informations sur l'assemblage...et activez "Rendre l'assemblage COM-Visible"
    • Sous Signature, activez Signer l'assembly et créez ou sélectionnez un fichier de clé de nom fort existant.
  • Écrire et construire la bibliothèque

    • Les classes COM Interop doivent avoir un constructeur par défaut et seules les classes et méthodes non statiques sont publiées
  • Copiez le .dll dans le dossier/la machine souhaitée

  • Enregistrez le .dll pour COM à l’aide de RegAsm

Par exemple (ajustez si nécessaire) :

"C:\Windows\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe" "C:\path\to\assembly.dll" /tlb /codebase
  • Appeler l’assembly depuis ASP

Par exemple (ajustez si nécessaire) :

Dim obj, returnValue
Set obj = Server.CreateObject("MyProject.MyClass")
returnValue = obj.DoSomething(param1, param2)

Note:

  • l'assembly doit être réenregistré via RegAsm lors de sa mise à jour

Voir également:

L'injection SQL doit être gérée à l'aide de requêtes SQL paramétrées.Non seulement cela éliminera le risque de sécurité, mais cela accélérera considérablement les performances de votre base de données car elle pourra réutiliser un plan d'exécution au lieu de le recalculer à chaque fois.La suggestion de le gérer via des remplacements de chaînes est insensée.VB est terrible dans la gestion des chaînes et ces instructions "remplacer" seront extrêmement coûteuses en performances et en mémoire (de plus, vous n'avez en fait besoin de gérer que le caractère ' de toute façon)

Déplacer le code vers .net ne l'améliore pas.Avoir du code de base de données dans vos pages n'est pas mauvais ;surtout si vous parlez d'un petit site avec seulement quelques développeurs.Des milliers de sites utilisent cette technique pour traiter des milliards de dollars de transactions.Maintenant, SQL dynamique non paramétré est mauvais et vous devriez travailler pour l'éliminer, mais cela ne nécessite pas de réécriture de l'application ou de .net pour le faire.Je suis toujours curieux de savoir pourquoi les gens voient .net comme une amélioration de facto de leur application.La plupart du mauvais code et des mauvaises habitudes qui existaient dans le modèle COM se propagent simplement lors d'une conversion.

Soit vous devez vous engager à créer une conception OO véritablement cohérente et à couplage minimal ;ou continuez simplement ce que vous avez parce que ce n’est pas si mal.

Dommage que je n'ai pas vu cette question en 2008.Pour moi, il semble que votre site utilise le framework Justa.Un moyen simple consiste à modifier le code Justa pour soumettre la recherche et les entrées de données au code urlencode.Je l'ai fait et cela fonctionne parfaitement pour moi.

Reste du code suffisamment sécurisé pour empêcher toute injection de type OS SQL ou toute autre tentative d'accès à la base de données.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top