2013-07-17 2 views
10

Есть ли простой способ преобразования:Преобразование строки в динамическом объекте

string str = "a=1,b=2,c=3"; 

в:

dynamic d = new { a = 1, b = 2, c = 3 }; 

Я думаю, что я мог бы написать функцию, которая делит строку и петлю результатов для создания динамический объект. Мне просто интересно, был ли более элегантный способ сделать это.

+0

Что вы ожидаете значения быть? Всегда 'int'? –

+0

@SimonL Нет, значения могут быть любыми типами данных. – Coltech

+0

Когда вы говорите _any_, это может быть класс? Или просто простые типы ('string', числовые типы) –

ответ

6

Вы можете использовать Microsoft Roslyn (here «s все-в-одном NuGet пакет):

class Program 
{ 
    static void Main(string[] args) 
    { 
     string str = "a=1,b=2,c=3,d=\"4=four\""; 
     string script = String.Format("new {{ {0} }}",str); 
     var engine = new ScriptEngine(); 
     dynamic d = engine.CreateSession().Execute(script); 
    } 
} 

И если вы хотите добавить еще более сложные типы:

string str = "a=1,b=2,c=3,d=\"4=four\",e=Guid.NewGuid()"; 
... 
engine.AddReference(typeof(System.Guid).Assembly); 
engine.ImportNamespace("System"); 
... 
dynamic d = engine.CreateSession().Execute(script); 

Основываясь на вопрос в вашем комментарии, есть уязвимости при инъекции кода. Добавьте System ссылку и пространство имен, как показано на рисунке справа выше, а затем заменить str с:

string str = 
    @" a=1, oops = (new Func<int>(() => { 
       Console.WriteLine(
        ""Security incident!!! User {0}\\{1} exposed "", 
        Environment.UserDomainName, 
        Environment.UserName); 
       return 1; 
      })).Invoke() "; 
+2

Это довольно интересно. Интересно, открывает ли он уязвимости для инъекций кода? Как ускользнуть от строки и выполнить случайный код, похожий на SQL-инъекцию? – Coltech

1

Вопрос, который вы описали, является чем-то вроде десериализации, то есть с целью создания объектов из формы данных (например, строки, байтового массива, потока и т. Д.). Надеюсь, эта ссылка поможет: http://msdn.microsoft.com/en-us/library/vstudio/ms233843.aspx

7

Я думаю, что если вы преобразуете «=» в «:» и обернете все фигурными скобками, вы получите действительную строку JSON.

Вы можете использовать Json.NET десериализации его в динамический объект:

dynamic d = JsonConvert.DeserializeObject<dynamic>(jsonString); 

Вы получите то, что вы хотите.

+1

Что делать, если строка содержит '=' –

+0

Я думаю, что вопрос касается только чисел, так или иначе это просто предложение , –

+0

Я просил разъяснений раньше. См. Комментарии исходного вопроса: это могут быть любые простые типы (включая строки). –

1

Вот решение, используя ExpandoObject, чтобы сохранить его после разбора его самостоятельно. Сейчас он добавляет все значения как string s, но вы можете добавить некоторый синтаксический анализ, чтобы попытаться превратить его в double, int или long (вы, вероятно, захотите попробовать его в этом порядке).

static dynamic Parse(string str) 
{ 
    IDictionary<String, Object> obj = new ExpandoObject(); 
    foreach (var assignment in str.Split(',')) 
    { 
     var sections = assignment.Split('='); 
     obj.Add(sections[0], sections[1]); 
    } 
    return obj; 
} 

использовать его как:

dynamic d = Parse("a=1,b=2,c=3"); 
// d.a is "1" 
+2

Опять же, проблема связана с тем, что строка может содержать символ ','. В этом случае неплохое расщепление не является хорошей идеей.Что делать, если вход: 'a = 1, b = 2, c = 'Это, мой друг, является строкой'' –

+0

Хм, хорошая точка; но в этом отношении, что это за формат? Является ли '' 'допустимым разделителем строк? Как насчет '' '? Как вы избегаете этих разделителей, если хотите, чтобы они были в строке? Короче говоря, я не знаю, что формат очень хорошо определен. –

+0

Согласен, мы мало знаем о вводе и как он был дезинфицирован (и если он вообще контролирует его) –

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