ASP에서 웹 서비스를 사용하는 경우 레코드세트 개체로 무엇을 합니까?

StackOverflow https://stackoverflow.com/questions/55297

문제

현재 나는 나쁜 오래된 spagethi 코드 패션에 직접 사용되는 레코드 세트 개체가 있는 고전적인(이전) ASP 웹 페이지를 실행하고 있습니다.

관리 효율성을 향상시키기 위해 asp.net에서 웹 서비스로 데이터 계층을 구현하려고 합니다.이는 웹사이트를 asp.net으로 업그레이드하기 위한 첫 번째 단계이기도 합니다.사이트 자체는 현재 ASP로 유지됩니다...

레코드세트 개체 유형을 웹 서비스 호환 유형(예: 배열 등)으로 바꾸는 좋은 방법을 추천할 수 있는 사람이 있습니까?아래를 무엇으로 바꾸나요?:

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

또한 여러 레코드세트를 대체할 수 있습니까?나는 말하고있다 :

 set objRS = objRs.nextRecordset 

누구든지 이 일을 겪었고 추천할 수 있나요?

@AdditionalInfo - 요청하셨습니다 :-)

처음부터 시작하겠습니다.기존 상황은:저장 프로시저를 통해 데이터베이스에서 가져온 고전적인 계층적 콘텐츠(헤더, 섹션, 하위 섹션, 콘텐츠)가 있는 오래된 ASP 웹 사이트가 있고 콘텐츠 페이지도 데이터베이스에 있습니다(html 파일에 대한 링크).

이제 나쁜 점은 ASP 코드가 많은 .asp 파일에 분산되어 있으며 모두 자체 데이터베이스 연결, 읽기, 쓰기(컨텐츠를 등록해야 함)를 수행한다는 것입니다.최근에 SQL 주입 공격에 문제가 있어서 이를 해결해 달라는 요청을 받았습니다.

~할 수 있었다 SQL 주입을 방지하기 위해 모든 .asp 페이지를 변경해야 하지만 그건 미친 짓입니다.그래서 저는 데이터 레이어를 구축하려고 생각했습니다. 모든 페이지는 이 레이어를 사용하여 데이터베이스에 액세스했습니다.DB 액세스 코드를 수정하고 업데이트할 수 있는 장소입니다.

결정을 내리면서 asp.net 업그레이드가 멀지 않다고 생각했습니다. 데이터 계층에 asp.net을 사용하는 것이 어떨까요?이렇게 하면 사이트를 업그레이드할 때 다시 사용할 수 있습니다.

그러면 위의 질문이 떠오릅니다!

도움이 되었습니까?

해결책

클래식 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

물론 기본 클래스를 확장하여 매개변수화된 저장 프로시저나 기타 유효성 검사 등을 처리할 수 있습니다.

다른 팁

이번 주에 제가 가장 좋아하는 조언은 다음과 같습니다.웹 서비스를 로컬 개체로 취급하지 마십시오. 그렇지 않으면 매우 높은 성능 비용을 지불하게 됩니다.기본적으로 웹 애플리케이션에서는 다음과 같은 작업을 수행하지 마세요.

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

항상 웹 서비스(및 SQL)에 대한 호출을 최소화하는 것을 선호해야 합니다.

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

이제 웹 서비스 호출에 사용할 데이터 유형에 대해서는 기본적으로 두 가지 선택이 있습니다.

  • 데이터세트
  • 그 밖의 모든 것(배열)

웹 서비스(예: List<MyData>)에서 반환된 대부분의 컬렉션은 실제로 웹 서비스 호출 중에 배열로 변환됩니다.웹 서비스는 개체(데이터 + 동작)를 반환하지 않고 데이터 구조(또는 시퀀스)만 반환한다는 점을 기억하십시오.따라서 목록과 배열 사이에는 거의 차이가 없습니다.

DataSet은 더 복잡한 클래스입니다.그들은 자체 사용자 정의 직렬 변환기를 사용하고 호출 애플리케이션에서 거의 완전히 다시 생성됩니다.이와 같은 DataSet을 사용하면 성능에 대한 비용이 발생하므로 일반적으로 대부분의 시나리오에서는 권장하지 않습니다.배열을 사용하여 데이터를 앞뒤로 전달하는 것이 더 효율적인 경향이 있으며 솔직히 말해서 더 쉽습니다.

귀하의 경우는 약간 다릅니다.이미 ADO를 사용하고 있는 기존 사이트를 변환하고 있으므로 ADO.NET DataSet이 가장 좋은 업그레이드 경로가 될 수 있습니다.ADO.NET과 ADO는 유사하므로 직접 업데이트하는 것이 더 쉬울 수 있습니다.웹 사이트가 어떻게 구축되었는지에 따라 다릅니다.

질문의 마지막 부분에서 DataSet은 ADO의 Recordset과 유사한 여러 레코드 세트를 지원합니다.이를 DataTable이라고 합니다.모든 DataSet에는 하나 이상의 DataTable이 있으며 순서에 관계없이 읽을 수 있습니다.

행운을 빌어요.

ASP 코드에서 XmlHttp 클래스를 사용하는 것이 좋습니다.

MyService.asmx에 이와 유사한 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에 대해 인터넷 검색을 하면 ASP 클래식에만 해당되는 특정 질문에 대한 답변을 얻을 수 있을 것입니다.

레이어별로 생각하는 대신 애플리케이션을 통해 수직 슬라이스를 가져와 이를 .net으로 변환해 보는 것은 어떨까요?이렇게 하면 분리된 부분 대신 .net으로 코딩된 전체 기능을 얻을 수 있습니다.사용자 경험을 개선하거나 기능을 추가하지 않고 완벽하게 작동하는 코드를 대체하는 비즈니스 가치는 무엇입니까?

또한 직접적인 ADO 호출에 비해 웹 서비스를 포기하게 될 성능의 균형을 고려할 수도 있습니다.웹 서비스는 공통 스키마에 액세스하는 여러 분리된 애플리케이션/팀 문제에 대한 좋은 솔루션입니다.단일 격리된 응용 프로그램을 더 유지 관리하기 쉽게 만들지 않고 더 느리고 더 복잡하게 만들 뿐입니다.

또 다른 대안은 COM Interop을 사용하여 클래식 ASP에서 호출할 수 있는 어셈블리를 .NET에서 만드는 것입니다.

Visual Studio에서 COM Interop 어셈블리를 만들려면(예:마이크로소프트 비주얼 C# 2005 익스프레스 에디션):

  • 새 클래스 라이브러리 프로젝트 만들기
  • 프로젝트 속성 열기

    • 응용 프로그램에서 어셈블리 정보...를 선택합니다."어셈블리 COM-Visible 만들기"를 활성화합니다.
    • 서명에서 어셈블리 서명을 활성화하고 기존 강력한 이름 키 파일을 생성하거나 선택합니다.
  • 라이브러리 작성 및 구축

    • 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을 통해 다시 등록해야 합니다.

또한보십시오:

SQL 삽입은 매개변수화된 SQL 쿼리를 사용하여 처리해야 합니다.이렇게 하면 보안 위험이 제거될 뿐만 아니라 실행 계획을 매번 다시 계산하는 대신 재사용할 수 있으므로 데이터베이스 성능이 크게 향상됩니다.문자열 교체를 통해 이를 처리하라는 제안은 어리석습니다.VB는 문자열을 처리하는 데 형편없으며 이러한 "교체" 문은 성능과 메모리 측면에서 극도로 비용이 많이 듭니다(또한 실제로는 ' 문자만 처리하면 됩니다).

코드를 .net으로 옮겨도 상황이 좋아지는 것은 아닙니다.페이지에 DB 코드를 포함하는 것은 나쁘지 않습니다.특히 개발자가 몇 명뿐인 소규모 사이트에 대해 이야기하고 있다면 더욱 그렇습니다.수천 개의 사이트가 이 기술을 사용하여 수십억 달러의 거래를 처리합니다.매개변수화되지 않은 동적 SQL은 좋지 않으며 이를 제거하기 위해 노력해야 하지만 이를 위해 앱이나 .net을 다시 작성할 필요는 없습니다.저는 왜 사람들이 .net을 앱의 실질적인 개선으로 보는지 항상 궁금합니다.COM 모델에 존재했던 대부분의 잘못된 코드와 나쁜 습관은 변환 중에 앞으로 전파됩니다.

진정으로 응집력 있고 최소한으로 결합된 OO 디자인을 만들기 위해 노력해야 합니다.아니면 그냥 지금 하고 있는 일을 그대로 유지하세요. 그렇게 나쁘지는 않으니까요.

안타깝게도 2008년에는 이 질문을 보지 못했습니다.제가 보기에는 귀하의 사이트가 Justa 프레임워크를 사용하고 있는 것 같습니다.간단한 방법은 검색 및 데이터 입력을 urlencode에 제출하기 위해 Justa 코드를 수정하는 것입니다.나는 그것을 해냈고 나에게 완벽하게 일했습니다.

나머지 코드는 모든 유형의 SQL 주입이나 기타 데이터베이스에 침입하려는 시도를 방지할 수 있을 만큼 충분히 안전합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top