asp使用Web服务,如何处理记录集对象?

时间:2008-09-10 20:50:32

标签: asp.net web-services asp-classic

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

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

有人可以推荐一种用Web服务兼容类型(如数组或类似内容)替换记录集对象类型的好方法吗? 我在下面用?:

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

并且mutliple记录集可以替换为? 我在说:

 set objRS = objRs.nextRecordset 

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

@AdditionalInfo - 您要求: - )

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

现在不好的是,ASP代码到处传播许多.asp文件都在做自己的数据库连接,读取,写入(你必须注册内容)。最近我们遇到了SQL注入攻击的问题,因此我被要求修复它。

可以更改所有.asp页面以防止sql注入,但那将是疯狂的。所以我想构建一个数据层 - 所有使用该层访问数据库的页面。一旦修复和更新数据库访问代码。

为了做出这个决定,我认为asp.net升级并不遥远,为什么不开始使用asp.net进行数据层?通过这种方式,可以在升级站点时重复使用它。

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

7 个答案:

答案 0 :(得分:4)

本周我最喜欢的建议是:如果是本地对象,或者要支付非常高的性价,请不要将您的Web服务视为它。基本上,不要在Web应用程序中执行以下操作:

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

您应该始终更喜欢最小化对Web Service(和SQL)的调用:

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

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

  • 数据集
  • 其他所有(数组)

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

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

你的情况有点不同;因为您要转换已使用ADO的现有站点,ADO.NET DataSet可能是您最好的升级路径。 ADO.NET和ADO足够相似,直接更新可能更容易。这取决于您的网站是如何构建的。

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

祝你好运。

答案 1 :(得分:1)

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

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

[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的Google搜索可能会回答您遇到的任何具体问题,因为它是针对ASP classic的。

答案 2 :(得分:1)

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

您可能还会考虑通过直接ado调用将Web服务放弃的性能权衡。 Web服务是解决多个不相交的应用程序/团队访问公共模式的问题的良好解决方案;它们不会使单个隔离的应用程序更易于维护,只会更慢,更复杂。

答案 3 :(得分:1)

如果您想坚持使用Classic ASP,那么我建议您通过ASP Classes创建一个数据库处理对象,然后使用该对象来创建记录集。这将集中您的数据库处理代码并使其成为您只需在单个位置处理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

当然,你可以扩展基本类来处理参数化的存储过程或者什么不是更多的验证等。

答案 4 :(得分:1)

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

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

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

    • 在应用程序下选择装配信息...并启用“使装配COM可见”
    • 在签名启用下签署程序集并创建或选择现有的强名称密钥文件
  • 编写并构建库

    • COM Interop类必须具有默认构造函数,并且只发布非静态类和方法
  • 将.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重新注册

另见:

答案 5 :(得分:1)

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

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

您需要承诺创建一个真正具有凝聚力,最小耦合的OO设计;或者只是保持你的目标,因为它并不是那么糟糕。

答案 6 :(得分:1)

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

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