2013-07-17 22 views
10

C'è un modo semplice per convertire:Converti stringa in oggetto dinamico

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

in:

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

Penso che probabilmente potrei scrivere una funzione che divide la stringa e loop i risultati per creare l'oggetto dinamico. Mi chiedevo solo se esistesse un modo più elegante per farlo.

+0

Che cosa si aspetta il valore di essere? Sempre 'int'? –

+0

@SimonL No, i valori potrebbero essere qualsiasi tipo di dati. – Coltech

+0

Quando dici _any_, potrebbero essere anche le classi? O solo tipi semplici ('string's, tipi di numeri) –

risposta

6

È possibile utilizzare Microsoft Roslyn (here s' all-in-one package 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); 
    } 
} 

E se si desidera aggiungere tipi ancora più complesse:

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

Sulla base della domanda nel tuo commento, ci sono vulnerabilità di iniezione di codice. Aggiungere il riferimento System e spazio dei nomi come mostrato proprio sopra, quindi sostituire il str con:

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

Questo è piuttosto interessante. Mi chiedo se si apre vulnerabilità di iniezione di codice? Come sfuggire alla stringa ed eseguire codice casuale simile a sql injection? – Coltech

7

Penso che se converti il ​​"=" in ":" e avvolgi tutto con parentesi graffe otterrai una stringa JSON valida.

È quindi possibile utilizzare JSON.NET di deserializzare in un oggetto dinamico:

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

Otterrete ciò che si desidera.

+1

Cosa succede se una stringa contiene' = ' –

+0

Penso che la domanda riguardi solo i numeri, comunque è solo un suggerimento . –

+0

Ho chiesto chiarimenti prima. Vedi i commenti della domanda originale: può essere qualsiasi tipo semplice (comprese le stringhe). –

1

Ecco una soluzione che utilizza ExpandoObject conservarlo dopo l'analisi da soli. In questo momento aggiunge tutti i valori come string s, ma è possibile aggiungere qualche parsing per provare a trasformarlo in un double, int o long (probabilmente si vorrebbe provarlo in questo ordine).

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

utilizzarlo come:

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

Ancora, il problema deriva dal fatto che una stringa potrebbe contenere un ','. La spaccatura cieca non è una buona idea in questo caso.Cosa succede se l'input è: 'a = 1, b = 2, c = 'Questo, amico mio, è una stringa'' –

+0

Hm, buon punto; ma del resto, cos'è esattamente questo formato? '' 'Un separatore di stringhe valido? Che ne dici di ""? "Come puoi sfuggire a quei separatori se ne vuoi uno nella stringa? In breve, non so se il formato è molto ben definito –

+0

D'accordo, non sappiamo molto sull'input e su come è stato sterilizzato (e se ne ha il controllo completo) –