asp, использующий веб-службу, что делать с объектом набора записей?

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

Вопрос

В настоящее время я запускаю классическую (старую) веб-страницу 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-инъекций, поэтому меня позвали, чтобы это исправить.

я мог пойдите, измените все страницы .asp, чтобы предотвратить внедрение sql, но это было бы безумием.Поэтому я подумал создать уровень данных — все страницы, использующие этот уровень для доступа к базе данных.Однажды место для исправления и обновления кода доступа к базе данных.

Приняв это решение, я подумал, что обновление 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>), фактически преобразуются в массив во время вызова веб-службы.Помните, что веб-службы возвращают не объекты (данные + поведение), а только структуры данных (или их последовательность).Таким образом, между списком и массивом нет большой разницы.

DataSets — более сложные классы;они используют собственный сериализатор и практически полностью воссоздаются в вызывающем приложении.За использование таких наборов данных приходится платить за производительность, поэтому я обычно не рекомендую его для большинства сценариев.Использование массивов для передачи данных туда и обратно, как правило, более эффективно и, откровенно говоря, это проще сделать.

Ваш случай немного другой;поскольку вы конвертируете существующий сайт, который уже использует ADO, лучшим вариантом обновления может быть набор данных ADO.NET.ADO.NET и ADO достаточно похожи, поэтому прямое обновление может оказаться проще.Это отчасти зависит от того, как построен ваш веб-сайт.

Что касается последней части вашего вопроса, наборы данных поддерживают несколько наборов записей, аналогичных набору записей ADO.Они называются DataTables.В каждом наборе данных есть хотя бы одна таблица данных, и вы можете читать их в любом порядке.

Удачи.

Я бы предложил использовать класс XmlHttp в вашем коде ASP.

Предполагая, что у вас есть веб-служба ASMX, подобная этой, в 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.

Поиск в Google информации о MSXML2, вероятно, ответит на любые ваши конкретные вопросы, поскольку он специфичен для классического ASP.

Вместо того, чтобы мыслить слоями, почему бы не попробовать сделать вертикальные срезы приложения и преобразовать их в .net.Таким образом, вы получите целые функции, закодированные в .net, а не разрозненные части.Какова ценность для бизнеса замены идеально работающего кода без улучшения пользовательского опыта или добавления функций?

Вы также можете рассмотреть компромисс между производительностью, от которой вы собираетесь отказаться, используя веб-службу, по сравнению с прямыми вызовами ADO.Веб-службы являются хорошим решением проблемы, когда несколько разрозненных приложений/команд получают доступ к общей схеме;они не делают отдельное изолированное приложение более удобным в обслуживании, а лишь делают его медленнее и сложнее.

Другой альтернативой является использование COM Interop для создания сборки в .NET, которую можно вызывать из классического ASP.

Чтобы создать сборку COM Interop из Visual Studio (например,Microsoft Visual C# 2005, экспресс-выпуск):

  • Создайте новый проект библиотеки классов.
  • Откройте свойства проекта

    • В разделе «Приложение» выберите «Информация о сборке...».и включите «Сделать сборку COM-видимой»
    • В разделе «Подписание» включите «Подписать сборку» и создайте или выберите существующий файл ключа строгого имени.
  • Напишите и создайте библиотеку

    • Классы COM Interop должны иметь конструктор по умолчанию, и публикуются только нестатические классы и методы.
  • Скопируйте .dll в нужную папку/компьютер.

  • Зарегистрируйте .dll для COM с помощью RegAsm.

Например (при необходимости откорректируйте):

"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 не улучшит его.Иметь код базы данных на своих страницах неплохо;особенно, если вы говорите о небольшом сайте, на котором работает всего пара разработчиков.Тысячи сайтов используют эту технику для обработки транзакций на миллиарды долларов.Непараметризованный динамический SQL — это плохо, и вам следует поработать над его устранением, но для этого не требуется переписывать приложение или .net.Мне всегда любопытно, почему люди рассматривают .net как фактическое улучшение своего приложения.Большая часть плохого кода и вредных привычек, существовавших в модели COM, просто распространяются во время преобразования.

Вам либо нужно взять на себя обязательство создать по-настоящему связный, минимально связанный объектно-ориентированный дизайн;или просто продолжайте то, что у вас есть, потому что это не так уж и плохо.

Жаль, что я не увидел этот вопрос в 2008 году.Мне кажется, что ваш сайт использует фреймворк Justa.Простой способ — изменить код Justa для отправки поиска и ввода данных в urlencode.Я сделал это и отлично работает для меня.

Остальная часть кода достаточно безопасна, чтобы предотвратить любые SQL-инъекции или другие попытки проникновения в базу данных.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top