ASP.net VB搜索引擎

时间:2011-09-06 18:04:10

标签: asp.net sql vb.net web-services foreach

我有一个搜索引擎,应该搜索产品的描述,然后会显示一些产品列表,其中包含用户正在寻找的任何字词或短语。我没有为使用该描述的产品制作任何类型的列表。

我只需要弄清楚为什么我的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 个答案:

答案 0 :(得分:3)

马上我发现你的代码存在三个问题:

  1. 正如您所说,您的代码很容易受到SQL注入攻击。你把它放到现场,任何关心尝试的人都完全拥有你的数据库。它甚至都不难。 “让它先工作”战略是一种完全倒退和错误的方法。太像这样的代码经常使它生产。
  2. 您正在使用LIKE运算符搜索冗长的文本列。这将扼杀数据库性能的生命。这是全文索引和CONTAINS函数的绝佳位置。关于搜索时间,这将是白天和黑夜。
  3. 您并不总是关闭数据库连接。如果抛出异常,您将泄漏打开的连接对象,这最终会导致对您的数据库的有效拒绝服务攻击,这些攻击来自您自己的应用程序。数据库连接必须始终包含在try / finally块中。
  4. 这只是冰山一角,只是从略读中收集到的。我还没有开始深入阅读代码。


    这是一个更新(我知道很晚),基于修复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
    

答案 1 :(得分:0)

这是为项目更新WebService的方式。它现在运作得很好。

 <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

答案 2 :(得分:-1)

除了Joel的评论之外,你真的需要永远不要在你的代码中放置Select语句(即使在测试时)......永远。始终使用存储过程。现在我需要做的就是阅读你的web.config文件(假设你没有花时间加密它),阅读你的连接,我完全和完全访问你的所有数据。