2017-08-02 58 views
3

我有以下的JSON字符串作爲我的問題的例子:反序列化列表<string>從JSON來列出<object>

{ 
    "Code": "Admin", 
    "Groups": 
    [ 
     "Administrator", 
     "Superuser", 
     "User" 
    ] 
} 

而且我有一個名爲用戶使用如下代碼類...

[JsonObject(MemberSerialization.OptIn)] 
public class User 
{ 
    public User (string code) 
    { 
     this.Code = code; 
    } 

    [JsonProperty] 
    public string Code { get; set; } 

    [JsonProperty("Groups")] 
    private List<UserGroup> groups; 
    public List<UserGroup> Groups 
    { 
     if (groups == null) 
      groups = new List<UserGroup>(); 
     return groups; 
    } 
} 

...和一個名爲用戶組類 - 在這個例子 - 只有這幾行代碼:

public class UserGroup 
{ 
    public UserGroup (string code) 
    { 
     this.Code = code; 

     // Some code to fill all the other properties, just by knowing the code. 
    } 

    public string Code { get; set; } 

    // More properties 
} 

現在,我想要的是,上面顯示的JSON字符串將被反序列化爲一個用戶的實例,並且「Groups」數組中的所有字符串都應該反序列化爲帶有來自每個字符串的實例的List<UserGroup>。 此外 - 另一種方式 - 應該將用戶序列化爲只包含UserGroups的Code屬性的JSON字符串。

我通常不反序列化,但我創建一個用戶的實例,並使用此代碼填充它...

Newtonsoft.Json.JsonConvert.PopulateObject(jsonString, myUserInstance); 

...但如果我用上面所示的JSON字符串運行代碼的所有我得到的是以下情況例外:

Newtonsoft.Json.JsonSerializationException: 'Error converting value "Administrator" to type 'UserGroup'. 

我最後的要求是,我想UserGroup被序列化爲一個字符串數組只有當我序列化User。當我將一個UserGroup獨立作爲一個根對象序列化時,它應該正常序列化(具有所有屬性)。 (作爲比較,在Json.Net: Serialize/Deserialize property as a value, not as an object中,對象在所有情況下都被串行化爲一個字符串。)

+2

兩個選項。創建一個自定義JsonConverter,知道如何處理轉換或向類中添加隱式運算符以知道如何從字符串轉換 – Nkosi

+0

是否必須創建從String到UserGroup的JsonConverter以及從字符串到列表的其他方式oder List ? 你是什麼意思加入一個隱式運算符? –

+0

只是好奇,爲什麼不使用這個? [JsonProperty(「Groups」)] public string [] Groups {get;組; } –

回答

2

你將不得不寫一個轉換器爲UserGroup

這是基於什麼樣的問題

被描述一個簡單的轉換
public class UserGroupJsonConverter : JsonConverter { 

    public override bool CanConvert(Type objectType) { 
     return typeof(UserGroup) == objectType; 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { 
     return new UserGroup((string)reader.Value); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { 
     writer.WriteValue(((UserGroup)value).Code); 
    } 
} 

,然後更新User通過設置在JsonProperty屬性的ItemConverterType要注意轉換器的

[JsonObject(MemberSerialization.OptIn)] 
public class User { 
    public User(string code) { 
     this.Code = code; 
    } 

    [JsonProperty] 
    public string Code { get; set; } 

    private List<UserGroup> groups; 
    [JsonProperty("Groups", ItemConverterType = typeof(UserGroupJsonConverter))] 
    public List<UserGroup> Groups { 
     get { 
      if (groups == null) 
       groups = new List<UserGroup>(); 
      return groups; 
     } 
    } 
} 

現在這將允許JSON在示例

{ 
    "Code": "Admin", 
    "Groups": 
    [ 
     "Administrator", 
     "Superuser", 
     "User" 
    ] 
} 

如期望

var user = JsonConvert.DeserializeObject<User>(json); 

和被序列回到相同的格式被反序列化。

var json = JsonConvert.SerializeObject(user); 
+0

如果我這樣做,例如不想序列化我的用戶,但也許用戶組本身,它不使用此轉換器(如果我不告訴它),但會正常序列化它,與財產名稱等,對嗎? –

+0

@ChristophMett,是的。在上面的例子中,該屬性只應用於'User'對象的'Groups'屬性。如果你想僅僅序列化'UserGroup'對象,則轉換器不適用。 – Nkosi

0

Administrator是一個字符串,UserGroup是一個對象,所以這是一個類型不匹配。在你的代碼中規定的情況下有效的JSON是:

{ 
    "Code": "Admin", 
    "Groups": 
    [ 
     { 
      "Code":"Administrator" 
     }, 
     { 
      "Code":"Superuser" 
     }, 
     { 
      "Code":"User" 
     } 
    ] 
} 
+0

通常這是完全正確的,但在我的示例中,我不想將UserGroup的整個對象結構保存在JSON字符串中,但僅保存代碼。 代碼屬性足以讓我的代碼獲取整個UserGroup實例。因此,爲了不保存冗餘數據(我知道,它是JSON的一個幾乎必不可少的部分)我只想從JSON的代碼屬性中保存字符串,並且還希望反序列化從整個UserGroup實例中獲取代碼字符串。 –