ASP.net VB поисковая система - PullRequest
       4

ASP.net VB поисковая система

2 голосов
/ 06 сентября 2011

У меня есть поисковая система, которая должна искать по описаниям продуктов, а затем отображать что-то со списком продуктов, в которых есть любое слово или фраза, которую искал пользователь.Я не составил никакого списка для продуктов, которые используют описание.

Мне просто нужно выяснить, почему мое утверждение SELECT ничего не делает.Это либо тот, либо цикл For Each.

Вот что у меня есть:

 Public Function GetDescriptions(ByVal prefixText As String, ByVal count As Integer) As String()
    Dim MarketingSql As String = "Select MarketingID, MarketingType, MarketingData FROM Marketing WHERE MarketingType = 2 AND MarketingData LIKE '%" & prefixText & "%'"
    Dim sqlConn As New SqlConnection
    sqlConn.Open()
    Dim myCommand As New SqlCommand(MarketingSql, sqlConn)
    Dim myReader As SqlDataReader = myCommand.ExecuteReader()
    Dim myTable As New DataTable
    myTable.TableName = "DescriptionSearch"
    myTable.Load(myReader)
    sqlConn.Close()
    Dim items As String() = New String(myTable.Rows.Count - 1) {}
    Dim i As Integer = 0
    For Each dr As DataRow In myTable.Rows
        items.SetValue(dr("MarketingData").ToString(), i)
        i += 1
    Next
    Return items
End Function


<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
<script type="text/javascript">
function AutoCompleteClientMethod(source, eventArgs) {
    var value = eventArgs.get_value();
    window.location = ("/Product/Default.aspx?id=" + value)
} 
</script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="body" Runat="Server">
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    <Services>
        <asp:ServiceReference Path="DescriptionSearch.asmx" />
    </Services>
</asp:ScriptManager>
    <asp:TextBox ID="Search" runat="server" AutoComplete="off"></asp:TextBox>
    <asp:AutoCompleteExtender ID="AutoCompleteExtender1" runat="server" TargetControlID="Search" ServicePath="~/DescriptionSearch.asmx" ServiceMethod="GetDescriptions" MinimumPrefixLength="1" CompletionSetCount="255" EnableCaching="true" OnClientItemSelected="AutoCompleteClientMethod">
    </asp:AutoCompleteExtender>
</asp:Content>

Ответы [ 3 ]

3 голосов
/ 06 сентября 2011

Сразу же я вижу три большие проблемы с вашим кодом:

  1. Как вы говорите, ваш код уязвим для внедрения SQL. Вы делаете это вживую, и любой, кто захочет попробовать, полностью владеет вашей базой данных. Это даже не сложно. Стратегия «заставь это работать сначала» - совершенно обратный и неправильный способ приблизиться к этому. Слишком часто такой код поступает в производство.
  2. Вы ищете длинные столбцы текста с помощью оператора LIKE. Это высосет жизнь из вашей базы данных. Это отличное место для полнотекстового индекса и функции CONTAINS . Это будет день и ночь в отношении времени поиска.
  3. Вы не всегда закрываете соединение с базой данных. Если выдается исключение, вы будете пропускать открытые объекты соединения, и это может в конечном итоге привести к эффективной атаке типа «отказ в обслуживании» на вашу базу данных, исходящую из вашего собственного приложения. Соединения с базой данных должны всегда заключаться в блок try / finally.

И это только верхушка айсберга, почерпнутая из простого скимминга. Я еще даже не начал читать глубоко в коде.


Вот обновление (позднее, я знаю), основанное на самопринятом ответе, чтобы исправить проблему с инъекцией SQL:

 <WebMethod()> _
Public Function GetDescriptions(ByVal prefixText As String, ByVal count As Integer)
As List(Of String)
    Dim MarketingSql As String = "Select DISTINCT p.ProductID, p.ProductName 
      FROM Product p 
      INNER JOIN Marketing m ON p.ProductID = m.ProductID 
      INNER JOIN Picklist k ON k.PicklistID = m.MarketingData 
      WHERE m.MarketingTypeID = 2 AND k.Data LIKE '%' + @prefixText + '%' 
      ORDER BY p.ProductName ASC"

    Using sqlConn As New SqlConnection
      (System.Configuration.ConfigurationManager.ConnectionStrings
      ("LocalSqlServer").ConnectionString), _
          myCommand As New SqlCommand(MarketingSql, sqlConn)

        myCommand.Parameters.Add("@prefixText", SqlDbTypes.VarChar, 50).Value = prefixText
        sqlConn.Open()
        Using myReader As SqlDataReader = myCommand.ExecuteReader()
            While myReader.Read()
                Dim id As String = myReader("ProductID").ToString()
                Dim name As String = myReader("ProductName").ToString()
                items.Add(AjaxControlToolkit.AutoCompleteExtender.CreateAutoCompleteItem(name, id))
            End While
         End Using
     End Using
     Return items
End Function
0 голосов
/ 22 сентября 2011

Так обновлялся веб-сервис для проекта.Теперь все работает отлично.

 <WebMethod()> _
Public Function GetDescriptions(ByVal prefixText As String, ByVal count As Integer)
As String()
    Dim MarketingSql As String = "Select DISTINCT p.ProductID, p.ProductName 
FROM Product p 
INNER JOIN Marketing m ON p.ProductID = m.ProductID 
INNER JOIN Picklist k ON k.PicklistID = m.MarketingData 
WHERE m.MarketingTypeID = 2 AND k.Data LIKE '%' & @prefixText & '%' 
ORDER BY p.ProductName ASC"
    Using sqlConn As New SqlConnection
      (System.Configuration.ConfigurationManager.ConnectionStrings
      ("LocalSqlServer").ConnectionString)
    sqlConn.Open()
    Dim myCommand As New SqlCommand(MarketingSql, sqlConn)
    myCommand.Parameters.Add("@prefixText", SqlDbType.VarChar, 50).Value = prefixText
    Dim myReader As SqlDataReader = myCommand.ExecuteReader()
    Dim myTable As New DataTable
    myTable.TableName = "DescriptionSearch"
    myTable.Load(myReader)
    sqlConn.Close()
    Dim items As String() = New String(myTable.Rows.Count - 1) {}
    Dim i As Integer = 0
    For Each dr As DataRow In myTable.Rows
        Dim id As String = dr("ProductID").ToString()
        Dim name As String = dr("ProductName").ToString()
        Dim item As String = AjaxControlToolkit.AutoCompleteExtender.CreateAutoCompleteItem(name, id)
        items.SetValue(item, i)
        i += 1
    Next
    Return items
    End Using
End Function
0 голосов
/ 06 сентября 2011

В дополнение к комментариям Джоэля, вам действительно НИКОГДА не нужно вставлять операторы Select в ваш код (даже во время тестирования) ... Всегда. Всегда используйте хранимые процедуры. Сейчас все, что мне нужно сделать, это прочитать ваш файл web.config (при условии, что вы не потратили время на его шифрование), прочитать ваше соединение, и у меня есть полный и полный доступ ко всем вашим данным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...