Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert String Into Dynamic Object

Tags:

c#

dynamic

Is there a straightforward way of converting:

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

into:

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

I think I could probably write a function that splits the string and loops the results to create the dynamic object. I was just wondering if there was a more elegant way of doing this.

like image 296
Coltech Avatar asked Jul 17 '13 12:07

Coltech


4 Answers

I think if you convert the "=" into ":" and wrap everything with curly brackets you'll get a valid JSON string.

You can then use JSON.NET to deserialize it into a dynamic object:

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

You'll get what you want.

like image 182
Tamim Al Manaseer Avatar answered Nov 15 '22 21:11

Tamim Al Manaseer


You may use Microsoft Roslyn (here's the all-in-one NuGet package):

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);
    }
}

And if you want to add even more complex types:

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);

Based on the question in your comment, there are code injection vulnerabilities. Add the System reference and namespace as shown right above, then replace the str with:

string str =
    @" a=1, oops = (new Func<int>(() => { 
                Console.WriteLine(
                    ""Security incident!!! User {0}\\{1} exposed "",
                    Environment.UserDomainName,
                    Environment.UserName); 
                return 1; 
            })).Invoke() ";
like image 31
Alex Filipovici Avatar answered Nov 15 '22 19:11

Alex Filipovici


The question you described is something like deserialization, that is, contructing objects from data form(like string, byte array, stream, etc). Hope this link helps: http://msdn.microsoft.com/en-us/library/vstudio/ms233843.aspx

like image 1
lulyon Avatar answered Nov 15 '22 19:11

lulyon


Here's a solution using ExpandoObject to store it after parsing it yourself. Right now it adds all values as strings, but you could add some parsing to try to turn it into a double, int, or long (you'd probably want to try it in that order).

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;
}

Use it like:

dynamic d = Parse("a=1,b=2,c=3");
// d.a is "1"
like image 1
Tim S. Avatar answered Nov 15 '22 19:11

Tim S.