Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create Json Array with ServiceStack

Quite new to .NET. Still haven't gotten the hang of how to do dictionaries, lists, arrays, etc.

I need to produce this JSON in order to talk to SugarCRM's REST API:

{
    "name_value_list": {
        "assigned_user_name": {
            "name": "assigned_user_name",
            "value": "joe"
        },
        "modified_by_name": {
            "name": "modified_by_name",
            "value": "jill"
        },
        "created_by_name": {
            "name": "created_by_name",
            "value": "jack"
        }
    }
}

from this C# POCO, which plays nicely with ServiceStack:

public class lead {
    public string assigned_user_name { get; set; }
    public string modified_by_name { get; set; }
    public string created_by_name { get; set; }
}

I have to do this sort of conversion for lots of different classes, so I don't think it's wise to create another strongly typed class (ala Costomising the serialisation/serialised JSON in service stack)

I've looked through the ServiceStack docs, but maybe I missed an example of this somewhere.

How do I build this JSON in a way that I can extend to other ServiceStack POCOs?

like image 871
cam Avatar asked Jun 10 '26 11:06

cam


2 Answers

This produces the right JSON:

        Dictionary<string, Dictionary<string, string>> nameValues = new Dictionary<string, Dictionary<string, string>>();

        // Deal with all the properties on the object
        IList<PropertyInfo> props = new List<PropertyInfo>(this.GetType().GetProperties());
        foreach (PropertyInfo prop in props)
        {
            Dictionary<string, string> nameValue = new Dictionary<string, string>();
            nameValue.Add("name", prop.Name);
            object propValue = prop.GetValue(this, null);
            if (propValue == null)
            {
                nameValue.Add("value", string.Empty);
            }
            else
            {
                nameValue.Add("value", prop.GetValue(this, null).ToString());
            }

            nameValues.Add(prop.Name, nameValue);
        }

        Dictionary<string, object> nameValuesArray = new Dictionary<string, object>();
        nameValuesArray.Add("name_value_list", nameValues);
        string jsonString = JsonSerializer.SerializeToString<Dictionary<string, object>>(nameValuesArray);

The reflection stuff is so that I can use it on any object later.

It's just a matter of constructing the right dictionary for the desired JSON output - in this case a dictionary -> dictionary -> dictionary. Trial and error... :/

Update

Altered it slightly (thanks paaschpa) to use a generic NameValue class because Dictionaries look ugly. I also got the requirements wrong. The JSON should be this:

[
    {
        "name": "id",
        "value": "60e03cb3-df91-02bd-91ae-51cb04f937bf"
    },
    {
        "name": "first_name",
        "value": "FancyPants"
    }
]

which you can do like this:

public class NameValue
{
    public string name { get; set; }
    public string value { get; set; }
}

public class Lead
{
    public string assigned_user_name { get; set; }
    public string modified_by_name { get; set; }
    public string modified_user_name { get; set; }

    public List<NameValue> toNameValues()
    {
        List<NameValue> nameValues = new List<NameValue>();

        IList<PropertyInfo> props = new List<PropertyInfo>(this.GetType().GetProperties());
        foreach (PropertyInfo prop in props)
        {
            NameValue nameValue = new NameValue();

            object propValue = prop.GetValue(this, null);
            if (propValue != null && !String.IsNullOrEmpty(propValue.ToString()))
            {
                nameValue.name = prop.Name;
                nameValue.value = propValue.ToString();
                nameValues.Add(nameValue);
            }
        }

        return nameValues;
    }
}

I'm leaving my original question as is (and my above answer) because it's still a legit example and proper JSON.

like image 133
cam Avatar answered Jun 12 '26 08:06

cam


Well, I don't think .NET dictionaries, lists, arrays, etc. will be helpful since the JSON you listed doesn't appear to have any arrays (square brackets) it in. I'm guessing most .NET JSON serializers will use square brackets when it hits these types. So, I think this leaves creating your own classes or doing some type of 'string magic' to produce to JSON you need.

Not exactly sure how you are using ServiceStack to talk to SugarCRM, but doing something like below should have ServiceStack.Text.JsonSerializer produce the JSON string you listed.

public class NameValue
{
    public string name { get; set; }
    public string value { get; set; }
}

public class Lead
{
    public NameValue assigned_user_name { get; set; }
    public NameValue modified_by_name { get; set; }
    public NameValue created_by_name { get; set; }
}

public class LeadRequest
{
    public Lead name_value_list { get; set; }
}

public void JsonTest()
{
    var req = new LeadRequest
        {
            name_value_list = new Lead
                {
                    assigned_user_name = new NameValue {name = "assigned_user_name", value = "joe"},
                    modified_by_name = new NameValue {name = "modified_by_name", value = "jill"},
                    created_by_name = new NameValue {name = "created_by_name", value = "jack"}
                }
        };

        var jsonReq  = ServiceStack.Text.JsonSerializer.SerializeToString(req);
}
like image 42
paaschpa Avatar answered Jun 12 '26 10:06

paaschpa