2013-08-12 3 views
2

Я сейчас пишу расширение заменить нормальный string.Format с моим FormatNamed -функцией.Метод расширения с динамическими именованными параметрами

До сих пор я получил этот код, но я хочу, чтобы изменить способ ввода параметров

void Main() 
{ 
    string sql = "SELECT {fields} FROM {table} WHERE {query}" 
     .FormatNamed(new { fields = "test", table = "testTable", query = "1 = 1" }); 
    Console.WriteLine(sql); 
} 

public static class StringExtensions 
{ 
    public static string FormatNamed(this string formatString, dynamic parameters) 
    { 
     var t = parameters.GetType(); 
     var tmpVal = formatString; 
     foreach(var p in t.GetProperties()) 
     { 
      tmpVal = tmpVal.Replace("{" + p.Name + "}", p.GetValue(parameters)); 
     } 
     return tmpVal; 
    } 
} 

Не самая красивая из Заменяет, но это делает работу.

В любом случае. Я хочу изменить его, чтобы выполнить его с помощью

.FormatName(field: "test", table: "testTable", query: "1 = 1"); 

Есть ли способ, которым я могу это сделать? Я пробовал поиск по динамическим именованным параметрам без каких-либо хороших результатов.

+5

Используйте sql-параметры для параметризации ваших запросов sql, не форматируйте строку sql самостоятельно, объединяя все поля и значения вместе. Вы открыты для атак sql-injectionn. –

+0

@TimSchmelter У нас есть код для дезинфекции SQL, но я не включил их здесь, мне просто нужна строка-пример. И SQL был первым, о котором я мог думать. :) – NoLifeKing

+0

Да, должно быть, с переводом. ^^ 'string phrase =" {item} будет стоить около {cost} в {storeName} -store ".Forma ...' – NoLifeKing

ответ

5

Вы не сможете указать произвольное количество динамических именованных параметров. это просто не то, что поддерживает C#. Ваш существующий код мне подходит, хотя я не вижу необходимости в параметре dynamic. Это будет работать точно так же:

public static string FormatNamed(this string formatString, object parameters) 
{ 
    var t = parameters.GetType(); 
    var tmpVal = formatString; 
    foreach(var p in t.GetProperties()) 
    { 
     tmpVal = tmpVal.Replace("{" + p.Name + "}", p.GetValue(parameters)); 
    } 
    return tmpVal; 
} 

А потом называть это как:

string sql = "SELECT {fields} FROM {table} WHERE {query}" 
    .FormatNamed(new { fields = "test", table = "testTable", query = "1 = 1" }); 

Хотя я действительно не советую использовать этот вид метода для построения SQL (это не избавит вас от SQL injection нападений вообще), сам метод звучит.

+0

+1 для SQL-инъекций, у нас есть функции для дезинфекции ввода, но для других, которые не имеет этого, это был действительный подход. – NoLifeKing

2

Я попытался прибегая к помощи динамических именованных параметров без каких-либо хороших результатов

Это потому, что способность не существует. Подумайте об этом - как функция узнает, что делать, если параметры и их имена не были известны во время компиляции? Самое близкое, о чем я могу думать, это использовать params, который дает вам массив значений, но все они должны быть одного типа, и вы все равно можете получить к ним доступ по заданному имени (и значению индекса).

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

.FormatName(new {field = "test", table = "testTable", query = "1 = 1"}); 

Это создает анонимный тип со свойствами указанного, который должен работать нормально с существующим кодом. Кроме того, для ввода всего лишь нескольких лишних символов.

Также обратите внимание, что dynamic не покупает вас здесь, так как он используется для доступа к свойствам напрямую без использования отражения. Поскольку вы используете рефлексию, чтобы получить пропозиции, вы можете просто использовать object.

+0

Вот как я выполняю текущий метод.:) – NoLifeKing

+0

@NoLifeKing и что не так с этим методом? У вас нет динамически названных параметров, о которых я знаю. –

+0

@NoLifeKing жаль, что я не видел, что вы использовали его таким образом, так как я не прокрутил право, чтобы увидеть остальную часть вашего кода. Я переформатирую его для вас, так что это яснее. –

Смежные вопросы