2013-06-26 90 views
3

很新的.NET。还没忘了怎么办字典,列表,数组的窍门等创建JSON数组与ServiceStack

我需要以交谈的SugarCRM的REST API产生这种JSON:

{ 
    "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文档,但也许我错过了这个地方的例子。

如何建立这个JSON的方式,我可以扩展到其他ServiceStack波苏斯?

回答

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。

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

感谢您的回应!此解决方案涉及更改Lead对象并强烈地将其输入到所需的JSON中 - 这意味着我的其他服务必须处理sugarCRM的格式。在某些情况下这可能是可以的。 – cam

1

您可以创建为leadcustom serializer

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使这个通用的,并且该接口的所有实现注册这个自定义序列。

+0

这是一个很好的建议。我仍然需要能够将Lead作为普通的ServiceStack响应序列化 - 我想知道这是否会很好地发挥作用。 – cam

+0

啊,我不确定在自定义序列化函数内部是否有任何方法可以获取有关请求的任何类型的上下文,以便确定要使用哪种类型的序列化。也许更好的方法是使用请求或响应过滤器来控制序列化。 –