Преобразование строки в динамический объект
Есть ли простой способ преобразования:
string str = "a=1,b=2,c=3";
в
dynamic d = new { a = 1, b = 2, c = 3 };
Я думаю, что, возможно, я мог бы написать функцию, которая разбивает строку и обрабатывает результаты для создания динамического объекта. Мне просто интересно, был ли более элегантный способ сделать это.
Ответы
Ответ 1
Вы можете использовать Microsoft Roslyn (здесь все -in-one пакет 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
Я думаю, что если вы преобразуете "=" в ":" и обернете все фигурными скобками, вы получите действительную строку JSON.
Затем вы можете использовать JSON.NET для десериализации его в динамический объект:
dynamic d = JsonConvert.DeserializeObject<dynamic>(jsonString);
Вы получите то, что хотите.
Ответ 3
Вопрос, который вы описали, является чем-то вроде десериализации, т.е. конструирования объектов из формы данных (например, строки, байтового массива, потока и т.д.). Надеюсь, эта ссылка поможет: http://msdn.microsoft.com/en-us/library/vstudio/ms233843.aspx
Ответ 4
Вот решение, использующее 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"