2016-04-19 2 views
0
string[] theParms = ['parm1', 'parm2']; 
string theQuery = "SELECT something, somethingAgain " + 
        "FROM aDBTable " + 
        "WHERE something = '{?}'" + 
        "AND something <> '{?}'"; 

Ich brauche den die {?} S mit den definierten parms in theParms zu ersetzen.C# ersetzen Parameter in Abfrage mit definierten Werten

Gibt es irgendeine Art von Schleife in C#, die ich um eine Schleife durch den String einsetzen kann und Ersetzen jedes gefundene {?} Mit dem entsprechenden parm Wert?

Etwas wie folgt aus:

Erste Schleife:

SELECT something, somethingAgain 
FROM aDBTable 
WHERE something = 'parm1' AND something <> '{?}' 

Zweite Schleife:

SELECT something, somethingAgain 
FROM aDBTable 
WHERE something = 'parm1' AND something <> 'parm2' 

Gibt es irgendeine Art von REGEX oder gemeinsamer Rahmen Funktion, die die oben tun kann?

SQL-Injection-Check

bool injectionCheckin = new injectionCheck().inCheck(theFinalQuery); 

public class injectionCheck 
{ 
    public bool inCheck(string queryString) 
    { 
     var badWords = new[] { 
      "EXEC", "EXECUTE", ";", "-", "*", "--", "@", 
      "UNION", "DROP","DELETE", "UPDATE", "INSERT", 
      "MASTER", "TABLE", "XP_CMDSHELL", "CREATE", 
      "XP_FIXEDDRIVES", "SYSCOLUMNS", "SYSOBJECTS", 
      "BC_HOME_ADDRESS1", "BC_HOME_ADDRESS2", "BC_HOME_CITY", "BC_HOME_COUNTY", "BC_HOME_POSTAL", "BC_MAIL_ADDRESS1", 
      "BC_MAIL_ADDRESS2", "BC_MAIL_CITY", "BC_MAIL_COUNTY", "BC_MAIL_POSTAL", "BC_MAIL_STATE", "FLSA_STATUS", "GRADE", 
      "GRADE_ENTRY_DT", "HIGHEST_EDUC_LVL", "LAST_INCREASE_DT", "BC_SALP_DESCR", "BC_SALP_DESCRSHORT", "SAL_ADMIN_PLAN" 
     }; 
     string pattern = "(?<!\\w)(" + Regex.Escape(badWords[0]); 

     foreach (var key in badWords.Skip(1)) 
     { 
      pattern += "|" + Regex.Escape(key); 
     } 

     pattern += ")(?!\\w)"; 

     dynamic _tmpCount = Regex.Matches(queryString, pattern, RegexOptions.IgnoreCase).Count; 

     if (_tmpCount >= 1) 
      return true; 
     else 
      return false; 
    } 
} 
+1

Sie sollten vielleicht Parameter verwenden, um Injektionsprobleme zu vermeiden, aber ansonsten, was ist gegen eine einfache 'for' Schleife, wo Sie die erste Instanz von' {?} 'Mit Ihrem Parameter ersetzen? – Adwaenyth

+0

@Adwaenyth Dann in der Schleife was ist mit dem zweiten Vorkommen von {?} ... drittem Vorkommen ... etc usw.? – StealthRT

+1

Wirklich, benutze parametrisierte Abfragen – Pikoh

Antwort

2

Warum nicht einfach String.Format verwenden?

string[] theParms = new string[] { "parm1", "parm2" }; 
string theQuery = @"SELECT something, somethingAgain 
        FROM aDBTable 
        WHERE something = '{0}' 
        AND something <> '{1}'"; 
var res = string.Format(theQuery, theParms); 

Ergebnis:

SELECT something, somethingAgain 
     FROM aDBTable 
     WHERE something = 'parm1' 
     AND something <> 'parm2' 
+0

Nizza Teo. Dies sollte gut für das, was ich tue, funktionieren. – StealthRT

+0

Wäre es möglich, diesen Code zu ändern, damit er {?} Anstelle von {0}, {1} usw. verwendet? – StealthRT

+0

@StealthRT Ich denke, dass es keinen Weg gibt. [Hier ein bisschen mehr Informationen] (http://stackoverflow.com/a/1426629/1849444). –

-1

Sie müssen es selbst nicht handhaben. Stattdessen können Sie mit ADO.NET Parameter definieren und ihre Werte festlegen. Sehen Sie das Beispiel hier. MSDN

+0

Dies ist nur ein Kommentar, keine echte Antwort auf diese Frage. – HimBromBeere

1

Wenn Sie es auf jeden Fall tun möchten, können Sie es wie folgt ohne eine Schleife machen.

string theQuery = String.Format("SELECT something, somethingAgain " + 
           "FROM aDBTable " + 
           "WHERE something = '{0}'" + 
           "AND something <> '{1}'", 
           theParams[0], theParams[1]); 
+2

Stinkt nach SqlInjection ... baaad Idee. – HimBromBeere

+1

** Gute Idee ** .. es prüft die Injektion ** AFTER ** es bildet die Abfrage (in meinem Fall). – StealthRT

+0

@StealthRT Wo wird die Injektion überprüft? – HimBromBeere

0

können Sie verwenden IndexOf und Teil jeder Instanz

for(int i = 0; i < theParms.GetLength(0); i++) 
{ 
    string[] tempStrings = new string[]{ theQuery.Substring(0,theQuery.IndexOf("{?}") - 1), 
    theQuery.Substring(theQuery.IndexOf("{?}"), 3), 
    theQuery.Substring(theQuery.IndexOf("{?}") + 4) } 
    tempStrings[1] = tempStrings[1].Replace("{?}", theParms[i]); 
    theQuery = String.Join("", tempStrings); 
} 

Obwohl zu sehen, wie Sie für die Injektion überprüfen, um zu finden, danach es auf jeden Fall viel besser zu bedienen String.Format

1

Okay, um Injektion zu vermeiden und all das, warum nicht Sie es wie folgt tun:

string[] theParms = // initialization 
string theQuery = // initialization 

SqlCommand cmd = new SqlCommand(/* enter connection string */, theQuery) 

for(int i = 0; i < theParams.Length; i++) 
{ 
    int index = cmd.Text.IndexOf("{?}"); 
    if(index > -1) 
    { 
     string pName = string.Format("@p{0}", i); 
     cmd.Text = cmd.Text.Remove(index, 3).Insert(index, pName); 
     cmd.Parameters.Add(new SqlParameter() { Name = pName, Value = theParms[i] }); 
    } 
} 

Das alltogether keine manuelle Injektion Kontrollen vermeiden sollten ... zumindest wenn man nicht die Abfrage vorkompiliert bekommen kann und es zur Laufzeit zu laden. Ansonsten formuliere einfach den Text des SqlCommands und du brauchst keine Schleife oder so etwas. Nur eine einfache Initialisierung:

SqlCommand cmd = new SqlCommand(/* enter connection string */, "SELECT something, somethingAgain FROM aDBTable WHERE something = @p0 AND something <> @p1"); 
cmd.Parameters.Add(new SqlParameter() { Name = "@p0", Value = theParms[0] }); 
cmd.Parameters.Add(new SqlParameter() { Name = "@p1", Value = theParms[1] }); 
2

immer Sql-Befehle von parameterized queries erstellen:

using (SqlConnection conn = new SqlConnection(DatabaseConnectionString)) 
using (SqlCommand cmd = conn.CreateCommand()) 
{ 
    var @params = new Dictionary<string, object>{ 
     { "something", myValue }, 
     { "somethingDifferent", anotherValue }, 
    }; 

    cmd.CommandText = "SELECT something, somethingAgain " + 
       "FROM aDBTable " + 
       "WHERE something = @something'" + 
       "AND something <> @somethingDifferent'"; 
    foreach (KeyValuePair<string, object> item in values) 
    { 
     cmd.Parameters.AddWithValue("@" + item.Key, item.Value); 
    } 

    DataTable table = new DataTable(); 
    using (var reader = cmd.ExecuteReader()) 
     { 
      table.Load(reader); 
      return table; 
     } 
    } 
} 

Diese alle Arten von SQL-Injection verhindert und Sie seltsame Kontrollen wie Sie mit dem badlist won't die ziemlich chaotisch und verhindert Sie nicht wirklich, Sie können die Liste leicht umgehen, indem Sie zum Beispiel flüchten.Insbesondere: Warum möchten Sie Ihre eigene Validierung schreiben, wenn es bereits fertige Methoden gibt, die genau das tun, was Sie wollen?

+0

Ich könnte mehr nicht zustimmen – Pikoh

Verwandte Themen