3

.NET 很新。仍然没有掌握如何做字典、列表、数组等。

我需要生成这个 JSON 以便与 SugarCRM 的 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"
        }
    }
}

来自这个 C# POCO,它与 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; }
}

我必须对许多不同的类进行这种转换,所以我认为创建另一个强类型类是不明智的(ala Costomising the serialisation/serialised JSON in service stack

我已经查看了 ServiceStack 文档,但也许我在某个地方错过了这个例子。

如何以可以扩展到其他 ServiceStack POCO 的方式构建此 JSON?

4

3 回答 3

3

这会产生正确的 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);

反射的东西是为了让我以后可以在任何对象上使用它。

只需为所需的 JSON 输出构建正确的字典 - 在本例中为字典 -> 字典 -> 字典。反复试验...:/

更新

稍微改变它(感谢 paaschpa)以使用通用 NameValue 类,因为字典看起来很难看。我也弄错了要求。JSON应该是这样的:

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

你可以这样做:

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

我保留我原来的问题(和我上面的答案),因为它仍然是一个合法的例子和正确的 JSON。

于 2013-06-26T19:12:44.790 回答
1

好吧,我认为 .NET 字典、列表、数组等不会有帮助,因为您列出的 JSON 似乎没有任何数组(方括号)。我猜大多数 .NET JSON 序列化程序会遇到这些类型时使用方括号。所以,我认为这留下了创建自己的类或执行某种类型的“字符串魔术”来生成您需要的 JSON。

不完全确定您如何使用 ServiceStack 与 SugarCRM 对话,但执行以下操作应该让 ServiceStack.Text.JsonSerializer 生成您列出的 JSON 字符串。

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);
}
于 2013-06-26T18:09:56.713 回答
1

您可以为该类创建一个自定义序列化lead程序。

JsConfig<lead>.SerializeFn = lead => {
    // Use reflection to loop over the properties of the `lead` object and build a dictionary
    var data = new Dictionary<string, object>();
    foreach (var property in typeof(lead).GetProperties()) {
        data[property.Name] = new {
            name: property.Name,
            value: property.GetValue(lead, null);
        };
    }
    return data.ToJson();
};

例如,您可以通过让所有要以这种方式序列化的类实现一个标记接口来使其通用ISugarCrmRequest,并为该接口的所有实现注册此自定义序列化程序。

于 2013-06-26T19:16:00.317 回答