首页 / 知识

关于asp.net:使用Web服务的ASP,记录集对象怎么办?

2023-04-14 21:40:00

关于asp.net:使用Web服务的ASP,记录集对象怎么办?

asp consuming a web service, what do do with recordset object?

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

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

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

1
2
3
4
5
6
set objRS = oConn.execute(SQL)
while not objRS.eof
   ...
   name = Cstr(objRS(1))
   ...
wend

而且也可以用多个记录集替换?
我在说话 :

1
 set objRS = objRs.nextRecordset

任何人都经历过,可以推荐吗?

@AdditionalInfo-您要求它:-)

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

现在的坏事是,到处都有ASP代码分布在许多.asp文件中,这些文件都进行自己的数据库连接,读取和写入(您必须注册内容)。最近,我们遇到了SQL注入攻击的问题,因此被要求对其进行修复。

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

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

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


首先,这是本周我最喜欢的建议:如果是本地对象,请不要像对待Web Service那样对待它,否则您将付出非常高的性能价格。本质上,请勿在Web应用程序中执行以下操作:

1
2
3
4
5
MyDataWebService ws = new MyDataWebService();
foreach(DataItem item in myData)
{
    ws.Insert(item);
}

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

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

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

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

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

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

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

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

祝好运。


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

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


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

将代码移至.net并不能使其更好。在页面中添加数据库代码还不错。特别是在id的情况下,您所谈论的是只有几个开发人员的小型网站。成千上万的站点使用该技术来处理数十亿美元的交易。现在,未参数化的动态sql不好,您应该消除这种情况,但这不需要重写应用程序或.net即可。我总是很好奇为什么人们将.net视作对他们应用程序的实际改进。 COM模型中存在的大多数不良代码和不良习惯只是在转换过程中向前传播。

您要么需要致力于创建一个真正有凝聚力的,最少耦合的OO设计;要么或者只是继续前进,因为那还不是很糟糕。


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

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

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

    • 在"应用程序"下,选择"程序集信息...",然后启用"使程序集COM可见"。
    • 在"签名"下,启用对程序集签名并创建或选择现有的强名称密钥文件
  • 编写并构建库

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

  • 使用RegAsm为COM注册.dll

例如(根据需要进行调整):

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

例如(根据需要进行调整):

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

注意:

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

也可以看看:

  • 将.NET Framework组件暴露给COM(MSDN)
  • CodeProject:从ASP页面调用.NET组件

如果您想坚持使用经典ASP,那么我建议您通过ASP类创建数据库处理对象,然后仅使用该对象创建记录集即可。这将集中您的数据库处理代码并使之集中,以便您仅需在单个位置处理SQL Injection攻击。

一个简单的例子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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

然后,要使用此功能,您可以将呼叫更改为:

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

当然,您可以扩展基本类以处理参数化的存储过程,或者不进行处理以及更多验证等。


与其分层次思考,不如尝试通过应用程序获取垂直切片并将其转换为.net。这样,您将获得用.net编码的全部功能,而不是不连贯的部分。在不改善用户体验或添加功能的情况下替换完美工作的代码有何商业价值?

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


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

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

1
2
3
4
5
[WebMethod]
public string HelloWorld()
{
  return"Hello World";
}

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

1
2
3
4
5
6
7
8
9
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响应:

1
<string>Hello World</string>

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

搜寻有关MSXML2的信息可能会回答您遇到的任何特定问题,因为它特定于ASP经典。


对象服务运行网页

最新内容

相关内容

猜你喜欢