webForumDet fria alternativet

Problem med att ha flera likadana item i en listbox

.NET

19 svar · 1 336 visningar · startad av saw

Medlem sedan mars 20011 880 inlägg
Frågan#1

Jag har två listboxar en med all tillgängl post samt den andra dit man kan
föra över ifrån den första.
Jag vill dock inte ha några dubbleter.
Detta sättet fungerade innan jag la till databasoperationer men inte nu
längre. Hur kan jag förbättra koden? :stud

itemText = ListBox1.SelectedItem.Text;
                ListItem lstitem = ListBox2.Items.FindByValue(itemText);
                if (lstitem != null)
                {
                    Label2.Text = "Tjänsten finn redan.";
                }

                else
                {
                    int anvId = Convert.ToInt32(ViewState["klientId"]);
                    sql = String.Format("INSERT INTO t_anstTjanst (anId,tjanst)
 VALUES ('{0}','{1}');", anvId, itemText);
                    Webbutill.executeSQL(sql, DBConn);
                    DBConn.Close();
                    sql = String.Format("SELECT id, tjanst FROM t_anstTjanst 
WHERE anId ={0};", anvId);
                    AccessDataSource4.SelectCommand = sql;
                    AccessDataSource4.DataBind();
                    ListBox2.Items.Add(itemText);
                    Label2.Text = "";
                }

Som det nu är så är det ingen hit.. :l

Medlem sedan mars 20011 880 inlägg
#2

Så dumt, jag kom på det att om jag kolla i databasen först, så fick jag det att fungera
bra.

Medlem sedan juni 20008 205 inlägg
#3

Det ser ut som att din kod öppnar för SQL-injektion. Men så är det väl inte? :)

Medlem sedan dec. 19996 721 inlägg
#4

Jag hoppas att du oftast har mer kontroll över SQL Injection än så där. Parametrisera allt.

Medlem sedan mars 20011 880 inlägg
#5

Jodå jag bygger in det med.
Jag gör så här:

 public static string fixaTecken(string strText)
    {
        string nText = string.Empty;
        nText = strText.Replace("_", "");
        nText = strText.Replace("´", "");
        nText = strText.Replace("|", "");
        nText = strText.Replace("@", "");
        nText = strText.Replace("$", "");
        nText = strText.Replace("'", "");
        return nText;
    }

Det skall väll räcka.

Medlem sedan mars 20023 561 inlägg
#6

Snyggare att ha en kollektion med IDbDataParameter (har för mig att interfacet heter så) som en parameter till din ExecuteSQL.

Medlem sedan mars 20011 880 inlägg
#7

Det var just snyggt, jag som helt nyligen lärt mig att skriva mina sql:er så här...

Medlem sedan juni 20008 205 inlägg
#8

Att ta bort tecken är inte rätt väg att gå :) se istället till att det blir säkert att stoppa in valfritt tecken. Parametriserade frågor. Sök här på forumet.

Medlem sedan mars 20011 880 inlägg
Medlem sedan juni 20008 205 inlägg
#10

Japp, det är det vi menar.

Medlem sedan mars 20011 880 inlägg
#11

Då gär jag någonting galet, jag får inga fel, men jag får inga påster heller...

 sql = "SELECT id, forId, tjanst FROM t_forTjanst WHERE forId =? ORDER BY t_forTjanst.tjanst";
        OleDbCommand cmd = new OleDbCommand("", DBConn);
        cmd.CommandText = sql;

         OleDbParameter paramforId = new OleDbParameter("@forId", DbType.Int32);
        paramforId.Value = "idforId";
        cmd.Parameters.Add(paramforId);

        DBConn.Open();
        OleDbDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
        while( dr.Read())
        {
            //ListBox1.Items.Add(new ListItem(ds.Tables[0].Rows[i]["tjanst"].ToString()));
            ListBox1.DataSource = dr;
            ListBox1.DataValueField = "id";
            ListBox1.DataTextField = "tjanst";
            ListBox1.DataBind();
        }

Var klantar jag mig?

Medlem sedan sep. 2005673 inlägg
#12

Du kan inte ha dr som datakälla i en while-loop, du kommer att skriva över tidigare rader hela tiden. Använd metoden add eller insert som du kommenterat bort, funkar inte det?

ListBox1.Items.Add(new ListItem(dr["tjanst"].ToString(), "value");
Medlem sedan mars 20011 880 inlägg
#13

Tack för att du försöker men jag får inte fram någon data i alla fall trots ditt fina försök.

Medlem sedan dec. 19996 721 inlägg
#14

DataReadern är redan en listbar datasource. Du behöver ingen while-loop.

OleDbDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
ListBox1.DataSource = dr;
ListBox1.DataValueField = "id";
ListBox1.DataTextField = "tjanst";
ListBox1.DataBind();
dr.Close();
Medlem sedan mars 20011 880 inlägg
#15

Tack emission även det har jag testat. Jag mistänker att felet är att forId (som
frågetecknet skall leta upp) det kommer ifrån

 DataTable dt = Webbutill.fillDataTable(DBConn, sql);
        if (dt.Rows.Count > 0)
        {
            DataRow row = dt.Rows[0];
            iId = Convert.ToInt32(row["Id"]);

.. ett annat resultat som jag får ut och jag tror att problemet är att jag
inte kan plocka ihop dom.

Medlem sedan dec. 19996 721 inlägg
#16

I did kod ovan står:

paramforId.Value = "idforId";

Men menar du inte...

paramforId.Value = idforId;

...eller något sånt? Du vill ju inte att den söka efter poster där forId='idforId'

Dessutom, om du använder en annan databasfråga för att plocka detta värde så är det rimligt att du borde kunna slå ihop frågorna med en join, men du kanske använder DataTable:n till annat också?

Medlem sedan mars 20011 880 inlägg
#17

Nu fungerar det tack för att ni har varit tålbodiga med mig. Jag har dock inte
fattat varför jag skall göra på det här sättet. Är det säkrare, snabbare,
stabilare eller?

För att jag skall förstå bättre, skall jag ha med alla fälten eller bara de som
är med i "WHERE"-satsen?
Vid en uppdate och insert så förstör jag att alla bör vara med, men hur blir
det då med "SQL-injektion" behöver jag inte köra med min replace-funktion?

Medlem sedan mars 20011 880 inlägg
#18

Tack vare att förra sql:en blev bra, så försöker jag på en ny, och misslyckas
naturligtvis. Jag får ingen data alls...

 string selListbox = ListBox1.SelectedItem.ToString();
        sql="SELECT t_anstPerson.Id, t_anstPerson.Namn, 
t_anstPerson.AnstNr, t_anstPerson.Tel, t_anstPerson.Mobil "+
        " FROM t_anstPerson  WHERE t_anstPerson.Namn=?";

        OleDbCommand cmd = new OleDbCommand("", DBConn);
        cmd.CommandText = sql;

        OleDbParameter paramforNamn = new OleDbParameter("@paramforNamn", DbType.Int32);
        paramforNamn.Value = selListbox;
        cmd.Parameters.Add(paramforNamn);

        DBConn.Open();
        
        OleDbDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);

        while (dr.Read())
        {
                LAnstNamn.Text = dr["Namn"].ToString(); 
        }
        dr.Close();

Är jag likväl på fel väg?

Medlem sedan dec. 19996 721 inlägg
#19

Är det säkrare, snabbare,
stabilare eller?

Ja (MYCKET), ja (VARIERANDE) och ja (MYCKET).

För att jag skall förstå bättre, skall jag ha med alla fälten eller bara de som
är med i "WHERE"-satsen?

Alla värden som kommer "utifrån". Om en SQL-sats tidigare så ut så här:

string sql = "UPDATE tabell set kolumn=" + värde + " WHERE annankolumn=1 AND tredjekolumn=" + annatvärde

..så ska den nu se ut så här:

string sql = "UPDATE tabell set kolumn=? WHERE annankolumn=1 AND tredjekolumn=?"

Vid en uppdate och insert så förstör jag att alla bör vara med, men hur blir
det då med "SQL-injektion" behöver jag inte köra med min replace-funktion?

Du ska inte använda replace-funktionen. Det sköts automatiskt och du behöver inte bry dig om farliga tecken.

Medlem sedan mars 20011 880 inlägg
#20

Nu har jag fått det mesta att fungera och jag tror att jag förstår principen.
Tack för all fin hjälp jag har fått.

265 ms totalt · 4 externa anrop · v20260731065814-full.6fe65c25
124 ms — deklarationer (db)
0 ms — hämta statistik (cache)
138 ms — hämta tråd, inlägg och bilagor (db)
121 ms — ändringar (db)