asp, потребляющий веб-сервис, что делать с объектом набора записей? - PullRequest
1 голос
/ 11 сентября 2008

В настоящее время я запускаю классическую (старую) веб-страницу ASP с объектом набора записей, который используется непосредственно в устаревшем устаревшем коде spagethi.

Я думаю о внедрении слоя данных в 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 для уровня данных? Таким образом, его можно использовать повторно при обновлении сайта.

Это подводит меня к вопросам выше!

Ответы [ 7 ]

4 голосов
/ 11 сентября 2008

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

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.

Теперь, что касается типа данных, используемых для вызовов веб-службы, у вас есть два варианта:

  • DataSet
  • Все остальное (массив)

Большинство коллекций, возвращаемых из веб-службы (например, List ), фактически преобразуются в массив при вызове веб-службы. Помните, что веб-сервисы не возвращают объекты (данные + поведение), а просто структуры данных (или последовательность). Поэтому между списком и массивом мало различий.

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

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

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

Удачи.

1 голос
/ 22 января 2011

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

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

1 голос
/ 21 сентября 2008

Внедрение SQL должно выполняться с использованием параметризованных SQL-запросов. Это не только устранит угрозу безопасности, но и значительно повысит производительность вашей базы данных, поскольку она сможет повторно использовать план выполнения вместо того, чтобы повторно вызывать его каждый раз. Предложение обрабатывать его путем замены строк глупо. VB плохо работает со строками, и эти операторы «замены» будут чрезвычайно дорогими по производительности и памяти (кроме того, вам все равно нужно обрабатывать символ 'в любом случае)

Перемещение кода в .net не делает его лучше. Наличие кода БД на ваших страницах неплохо; особенно, если вы говорите о маленьком сайте с парой разработчиков. Тысячи сайтов используют эту технику для обработки миллиардов долларов транзакций. Теперь непараметризованный динамический sql плох, и вы должны поработать над его устранением, но для этого не требуется переписывать приложение или .net. Мне всегда любопытно, почему люди видят .net как улучшение своего приложения. Большинство плохого кода и вредных привычек, которые существовали в модели COM, просто распространяются во время преобразования.

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

1 голос
/ 17 сентября 2008

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

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

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

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

    • Классы 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 при обновлении

Смотри также:

1 голос
/ 16 сентября 2008

Если вы хотите придерживаться Classic 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

Конечно, вы можете расширить базовый класс для обработки параметризованных хранимых процедур или чего-то еще, и больше проверок и т. Д.

1 голос
/ 11 сентября 2008

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

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

1 голос
/ 11 сентября 2008

Я бы предложил использовать класс 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.

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

...