1

目前,我运行一个经典(旧)ASP 网页,其中记录集对象直接用于糟糕的旧 spagethi 代码风格。

我正在考虑在 asp.net 中实现一个数据层作为 web 服务以提高可管理性。这也是将网站升级到 asp.net 的第一步。该网站本身仍然是 ASP 的时刻......

任何人都可以推荐一种用 Web 服务兼容类型(如数组或其他东西)替换记录集对象类型的好方法吗?我在下面用什么替换?:

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

并且还可以替换多个记录集?我在说话 :

 set objRS = objRs.nextRecordset 

有人经历过这个并可以推荐吗?

@AdditionalInfo - 你要求的:-)

让我从头开始。 现有情况是:我有一个旧的 ASP 网站,其经典的分层内容(标题、部分、小节、内容)通过存储过程从数据库中提取出来,并且内容页面也在数据库中(指向 html 文件的链接)。

现在糟糕的是,ASP 代码遍布在许多 .asp 文件中,所有这些文件都进行自己的数据库连接、读取、写入(您必须注册内容)。最近我们遇到了 SQL 注入攻击的问题,所以我被要求修复它。

可以去更改所有的 .asp 页面以防止 sql 注入,但这太疯狂了。所以我想建立一个数据层——所有页面都使用这个层来访问数据库。曾经修复和更新数据库访问代码的地方。

做出这个决定,我认为 asp.net 升级还很遥远,为什么不开始使用 asp.net 作为数据层呢?这样在升级站点时可以重复使用它。

这让我想到了上面的问题!

4

7 回答 7

4

首先,我本周最喜欢的建议是:如果您的 Web 服务是本地对象,请不要将其视为本地对象,否则您将付出非常高昂的性能代价。本质上,不要在你的 web 应用程序中做这样的事情:

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

您应该始终希望尽量减少对 Web 服务(和 SQL)的调用:

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

现在,就用于 Web 服务调用的数据类型而言,您基本上有两种选择:

  • 数据集
  • 其他一切(数组)

从 Web 服务返回的大多数集合(如 List<MyData>)实际上在 Web 服务调用期间转换为数组。请记住,Web 服务不返回对象(数据 + 行为),而只是返回数据结构(或一系列)。因此,列表和数组之间几乎没有区别。

DataSet 是更复杂的类;他们使用自己的自定义序列化程序,并且几乎可以在调用应用程序中完全重新创建。使用这样的 DataSet 需要付出性能成本,因此我通常不建议在大多数情况下使用它。使用数组来回传递数据往往更有效,坦率地说,它更容易做到。

你的情况有点不同;因为您正在转换已经使用 ADO 的现有站点,所以 ADO.NET 数据集可能是您最好的升级路径。ADO.NET 和 ADO 非常相似,因此直接更新可能会更容易。这取决于您的网站是如何构建的。

对于您问题的最后一部分,DataSet 确实支持类似于 ADO 的 Recordset 的多个记录集。它们被称为数据表。每个 DataSet 至少有一个 DataTable,您可以按任意顺序读取它们。

祝你好运。

于 2008-09-10T21:26:16.517 回答
1

我建议在您的 ASP 代码中使用 XmlHttp 类。

假设您在 MyService.asmx 中有一个与此类似的 ASMX Web 服务:

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

你可以在 ASP 中这样称呼它:

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 将是以下 XML 响应:

<string>Hello World</string>

假设您的服务返回了一组数据,您可以使用 XPath 或任何其他 XML 处理技术/库对其进行迭代。

谷歌搜索有关 MSXML2 可能会回答您的任何特定问题,因为它特定于 ASP 经典。

于 2008-09-10T21:40:51.770 回答
1

与其分层思考,不如尝试通过应用程序进行垂直切片并将其转换为 .net。这样,您将获得在 .net 中编码的整个功能,而不是不相交的部分。在不改善用户体验或添加功能的情况下替换完美运行的代码有什么商业价值?

您还可以考虑使用 Web 服务而不是直接 ado 调用来权衡性能。Web 服务是解决多个不相交的应用程序/团队访问公共模式问题的一个很好的解决方案;它们不会使单个孤立的应用程序更易于维护,只会更慢和更复杂。

于 2008-09-11T00:59:45.287 回答
1

如果您想坚持使用经典 ASP,那么我建议您通过 ASP 类创建一个数据库处理对象,然后只需使用该对象来创建记录集。这将集中您的数据库处理代码并使您只需在一个位置处理 SQL 注入攻击。

一个简单的例子。

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

然后要使用它,您可以将调用更改为:

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

当然,您可以扩展基本类来处理参数化存储过程或其他什么以及更多验证等。

于 2008-09-16T18:56:44.110 回答
1

另一种选择是使用 COM Interop 在 .NET 中创建可从经典 ASP 调用的程序集。

从 Visual Studio 创建 COM 互操作程序集(例如 Microsoft Visual C# 2005 Express Edition):

  • 创建一个新的类库项目
  • 打开项目属性

    • 在 Application 下选择 Assembly Information... 并启用“Make assembly COM-Visible”
    • 在签名下启用签名程序集并创建或选择现有的强名称密钥文件
  • 编写和构建库

    • COM 互操作类必须具有默认构造函数,并且仅发布非静态类和方法
  • 将 .dll 复制到所需的文件夹/机器

  • 使用 RegAsm 为 COM 注册 .dll

例如(根据需要调整):

"C:\Windows\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe" "C:\path\to\assembly.dll" /tlb /codebase
  • 从 ASP 调用程序集

例如(根据需要调整):

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

笔记:

  • 程序集在更新时必须通过 RegAsm 重新注册

也可以看看:

于 2008-09-17T04:07:27.250 回答
1

应该使用参数化的 sql 查询来处理 Sql 注入。这不仅会消除安全风险,还会显着提高数据库性能,因为它能够重用执行计划,而不是每次都重新计算它。通过字符串替换来处理它的建议是愚蠢的。VB 在处理字符串方面很糟糕,那些“替换”语句在性能和内存方面将非常昂贵(而且,你实际上只需要处理 ' 字符)

将代码移至 .net 并不能让它变得更好。在你的页面中有 db 代码还不错;特别是如果您正在谈论一个只有几个开发人员的小型网站。数以千计的网站使用这种技术来处理数以亿计的交易。现在,未参数化的动态 sql 很糟糕,您应该努力消除它,但这不需要重写应用程序或 .net 即可。我总是很好奇为什么人们将 .net 视为对其应用程序的事实上的改进。COM 模型中存在的大多数不良代码和不良习惯只是在转换过程中向前传播。

您要么需要承诺创建一个真正内聚的、最小耦合的 OO 设计;要么 或者只是保持你的状态,因为它并不是那么糟糕。

于 2008-09-21T06:14:05.077 回答
1

太糟糕了,我在 2008 年没有看到这个问题。对我来说,您的网站似乎正在使用 Justa 框架。简单的方法是修改 Justa 代码以将搜索和数据输入提交到 urlencode。我做到了,并且为我完美地工作。

其余代码足够安全,可以防止任何类型的 os SQL 注入或其他尝试进入数据库。

于 2011-01-22T15:30:07.730 回答