Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic Objects in WCF not possible?

When building a response in WCF (json), im pretty sure it's not possible to use completely dynamic objects, but just wanted to double check here first.

An ideal response would look something like:

"userTypes"  :
                    {
                        "BartSimpson" :
                            {
                                "url" : "foo",
                                "desc" : "bar"
                            },
                        "LisaSimpson" :
                            {
                                "url" : "foo",
                                "desc" : "bar"
                            }
                    }

In 'compiled' code, the above could be performed by the following architecture (slightly pseudocode):

public class Character{
string url {get;set;}
string desc{get;set;}
}

public class UserTypes{
 public Character BartSimpson{get;set;}
 public Character LisaSimpson{get;set;}
}

But my main goal is that BartSimpson and LisaSimpson are not 'compiled' so I could have any number of Character classes, with any name / identifer in the response.

like image 945
maxp Avatar asked Jul 23 '13 09:07

maxp


1 Answers

Add the following using at the top of your service implementation class (make sure that you also add the proper references in your project):

using Newtonsoft.Json;
using System.Dynamic;
using System.IO;
using System.Text;

You may try this simple method which outputs the dynamic result:

public string GetData()
{
    dynamic d = new ExpandoObject();
    dynamic bartSimpson = new ExpandoObject();
    dynamic lisaSimpson = new ExpandoObject();
    bartSimpson.url = "foo";
    bartSimpson.desc = "bar";
    lisaSimpson.url = "foo";
    lisaSimpson.desc = "bar";
    d.userTypes = new ExpandoObject();
    d.userTypes.BartSimpson = bartSimpson;
    d.userTypes.LisaSimpson = lisaSimpson;
    var s = JsonSerializer.Create();
    var sb = new StringBuilder();
    using (var sw = new StringWriter(sb))
    {
        s.Serialize(sw, d);
    }
    return sb.ToString();
}

To go one more step further (you'll just have to pass Bart and Lisa in the comaSeparatedNames value), you could do:

public string GetData(string comaSeparatedNames)
{
    string[] names = comaSeparatedNames.Split(',');
    dynamic d = new ExpandoObject();
    dynamic dNames = new ExpandoObject();
    foreach (var name in names)
    {
        dynamic properties = new ExpandoObject();
        properties.url = "foo";
        properties.desc = "bar";
        ((IDictionary<string, object>)dNames).Add(name, properties);
    }
    ((IDictionary<string, object>)d).Add("userTypes", dNames);

    var s = JsonSerializer.Create();
    var sb = new StringBuilder();
    using (var sw = new StringWriter(sb))
    {
        s.Serialize(sw, d);
    }

    // deserializing sample
    //dynamic dummy = new ExpandoObject();
    //var instance = s.Deserialize(new StringReader(sb.ToString()), 
    //    dummy.GetType());
    //var foo = instance.userTypes.BartSimpson.url;

    return sb.ToString();
}

Note: I've also provided the lines (commented) for deserialization.

like image 175
Alex Filipovici Avatar answered Sep 16 '22 17:09

Alex Filipovici