Im currently developing an webapplication that are going to have an Autocomplete search form, the results are being updated from an Sql Database. The whole “functionality” is working except of one thing. The client is calling an C# Webservice which are going to return an array to the client. The thing is. The list of the client shows the same results multiply times. So if theres only one match from the database the client shows that match like 20-25 times in an vertical list. I don’t know how to solve this, please help.
C# Webservice:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Data.SqlClient;
namespace WebApplication6
{
public class searchResult
{
public string Title;
public string img;
public string href;
}
/// <summary>
/// Summary description for WebService
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
[System.Web.Script.Services.ScriptService]
[System.Web.Script.Services.GenerateScriptType(typeof(searchResult))]
public class WebService : System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
[WebMethod]
public searchResult[] Search(string txtSearch)
{
//Semuler to slow internet connection
//System.Threading.Thread.Sleep(2000);
//Declare collection of searchResult
List<searchResult> resultList = new List<searchResult>();
string constr = System.Web.Configuration.WebConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString; ;
SqlConnection con = new SqlConnection(constr);
SqlCommand cmd = con.CreateCommand();
cmd.CommandText = "SELECT * FROM [DriverInfo], [Teams], [Tracks] WHERE UserName LIKE '" + txtSearch + "%' OR TeamName LIKE '" + txtSearch + "%' OR TrackName LIKE '" + txtSearch + "%'";
try
{
con.Open();
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
searchResult DriverResult = new searchResult();
DriverResult.Title = dr["UserName"].ToString();
DriverResult.img = "driver.png";
DriverResult.href = dr["UserId"].ToString();
if (DriverResult.Title.ToLower().Contains(txtSearch.ToLower()))
{
resultList.Add(DriverResult);
}
searchResult TeamResult = new searchResult();
TeamResult.Title = dr["TeamName"].ToString();
TeamResult.img = "team.png";
TeamResult.href = dr["Id"].ToString();
if (TeamResult.Title.ToLower().Contains(txtSearch.ToLower()))
{
resultList.Add(TeamResult);
}
searchResult TrackResult = new searchResult();
TrackResult.Title = dr["TrackName"].ToString();
TrackResult.img = "track.png";
TrackResult.href = dr["TrackId"].ToString();
if (TrackResult.Title.ToLower().Contains(txtSearch.ToLower()))
{
resultList.Add(TrackResult);
}
}
con.Close();
return resultList.ToArray();
}
catch
{
return null;
}
}
}
}
HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script src="http://code.jquery.com/jquery-1.4.3.min.js" type="text/javascript></script>
<link href="main.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
function search() {
if ($("#txtSearch").val() != "") {
$(".divResult").show(); //show div block that contains on result
$(".loading").show(); // show loading text while getting result
//call web searvice
$.ajax({ type: "POST",
url: "WebService.asmx/Search", //function that in web service
data: "{txtSearch:'" + $("#txtSearch").val() + "'}",// passing value of txtSearch input
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(response) {
//declaer client object and set to it returned result from web sevice function
var result = response.d;
$(".record").html(""); // clear previous result
//looping in 'result' array to get data and fill it inside ".record" div as html
$.each(result, function(index, res) {
//append img tag inside ".record" div
$('<img />', {
src: 'Images/' + res.img,
alt: res.Title
}).addClass("img").appendTo('.record');
//append anchor tag inside ".record" div
$('<a></a>', {
href: res.href,
text: res.Title
}).addClass("txtResult").appendTo('.record');
$(".record").append("<hr />");
});
//hide loading div when the data was got
$(".loading").hide();
},
error: function(msg) {
$(".record").html(msg.d);
}
});
}
else {
$(".divResult").hide(); //hide div that contains result when the input text is empty
$(".record").html(""); //also loading text when the input text is empty
}
}
</script>
</head>
<body>
<div class="content">
<input id="txtSearch" onkeyup="search()" type="text" />
<div class="divResult">
<div class="loading">Loading..</div>
<div class="record"></div>
</div>
</div>
</body>
</html>
CSS:
.content
{
margin:50px auto;
text-align:center;
width:322px;
}
#txtSearch
{
border:solid 1px #cccccc;
width:320px;
color:#555555;
font: 18pt tahoma;
height: 20px;
font-size: 12px;
font-family: "lucida grande",tahoma,verdana,arial,sans-serif;
}
.divResult
{
position:absolute;
background-color:#F2F2FF;
border-style:solid;
border-width:1px;
border-color:#999999;
width:320px;
text-align:left;
display:none;
}
.img
{
padding-top: 2px;
width:30px;
height:30px;
float:left;
}
.txtResult
{
display:block;
width:320px;
height:30px;
color:#3c5899;
font-family: "lucida grande",tahoma,verdana,arial,sans-serif;
font-size: 14px;
font-weight: bold;
text-decoration:none;
}
.txtResult:hover {
background-color: #3c5899;
color: White;
}
.loading
{
font: 10pt tahoma;
text-align:center;
}
.record
{
margin:0px;
}
The type of join you’re doing in your SQL query is not recommended, and it may account for your duplicate results. I’d suggest something more like this:
This would give you results like this:
Here’s how you could consume these results:
As is, you’re probably getting results like these (a cartesian product), where the number of results wont be
A + B + C, but ratherA * B * C:Also, notice that since
select *is being used, you’ll get more columns than you need.Update:
You said you weren’t sure with how to add your variables to the query. You should use a parameterized query instead of string concatenation to make your code cleaner and to protect against SQL injection attacks: