2013-06-26 126 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

啊,我不確定在自定義序列化函數內部是否有任何方法可以獲取有關請求的任何類型的上下文,以便確定要使用哪種類型的序列化。也許更好的方法是使用請求或響應過濾器來控制序列化。 –