将字符串转换为动态对象

本文关键字:动态 对象 转换 字符串 | 更新日期: 2023-09-27 18:22:43

是否有一种简单的转换方法:

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

进入:

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

我想我可能可以写一个函数来分割字符串并循环结果以创建动态对象。我只是想知道是否有一种更优雅的方式来做这件事。

将字符串转换为动态对象

我认为如果您将"="转换为":"并用大括号包装所有内容,您将获得一个有效的JSON字符串。

然后,您可以使用JSON.NET将其反序列化为一个动态对象:

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

你会得到你想要的。

您可以使用Microsoft Roslyn(这是一体式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() ";

您描述的问题类似于反序列化,即从数据形式(如字符串、字节数组、流等)构造对象。希望此链接能帮助:http://msdn.microsoft.com/en-us/library/vstudio/ms233843.aspx

下面是一个使用ExpandoObject在自己解析后存储它的解决方案。现在,它将所有值添加为strings,但您可以添加一些解析,尝试将其转换为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"