2017-06-04 48 views
3

編寫可重用JsonConverters我查詢返回多種格式的標籤列表的服務:爲json.net

{ 
    "tags": "a,b,c" 
} 

{ 
    "tags": "a b c" 
} 

{ 
    "tags": "a+b+c" 
} 

的對象,我想反序列化這是一個List<string>。我寫了一個TagsConverter實現在JsonConverter像這樣必要的方法:

public class TagsConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return (objectType == typeof(string)); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     return reader 
       .Value 
       .ToString() 
       .Split(' ') 
       .ToList(); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     var list = (List<string>)value; 
     var delimitedList = string.Join(" ", list); 

     writer.WriteValue(delimitedList); 
    } 
} 

然後我註釋字段中的對象,像這樣:

public class Foo 
{ 
    [JsonConverter(typeof(TagsConverter))] 
    public List<string> Tags { get; set; } 
} 

而這個工作,但只爲標記,由空格分隔。

但是,如果我能夠以參數化方式更改SplitJoin函數,則TagsConverter可以在所有3種情況下工作。但是由於我們只將該類型傳遞給JsonConverter屬性,因此我明白我們不能在此處傳遞「分隔符」作爲參數。

有什麼辦法可以達到這個目的嗎?

回答

3

有一個額外的JsonConverterconstructor overload這既需要一個類型注入到你的轉換器的具體實例的params object[] converterParameters。您可以利用這種過載來最大化您的可重用性。

public class TagsConverter : JsonConverter 
{ 
    private readonly string _delimiter; 

    public TagsConverter(string delimiter) 
    { 
     _delimiter = delimiter; 
    } 

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

    public override object ReadJson(JsonReader reader, Type objectType, 
     object existingValue, JsonSerializer serializer) 
    { 
     return reader 
       .Value 
       .ToString() 
       .Split(_delimiter.ToCharArray()) 
       .ToList(); 
    } 

    public override void WriteJson(JsonWriter writer, object value, 
     JsonSerializer serializer) 
    { 
     var list = (List<string>)value; 
     var delimitedList = string.Join(_delimiter, list); 

     writer.WriteValue(delimitedList); 
    } 
} 

利用過載是通過它作爲第二個參數一樣簡單:

public class Foo 
{ 
    [JsonConverter(typeof(TagsConverter), " ")] 
    public List<string> Tags { get; set; } 
} 
+0

我喜歡這個解決方案,但是不是你有兩個創建三個單獨的'Foo'類,每個都有一個分隔符? –

+0

@MariaInesParnisari根據所提供的代碼,是什麼讓你認爲這不是OP的意圖?據我所知,OP需要一個可重用的轉換器,可以應用於多個類別,每個類別採用不同的分隔符,這正是我所提供的。這就是說,如果你對這個問題有另一種解釋,我很樂意聽到它:)。 –

+0

不,我認爲這正是OP想要的。我只想着是否有一種替代方案可能涉及在'Foo'中使用泛型.. –

2

如果只有所需JSON的讀取/反序列化不注意,string.Split可以採取一個字符數組char[]

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
{ 
    return reader 
      .Value 
      .ToString() 
      .Split(new char[]{' ', ',', '+'}, StringSplitOptions.RemoveEmptyEntries) 
      .ToList(); 
} 

這意味着轉換器在讀取時可以處理所有三個分隔符。

+0

這也很棒。但是,我發現David提出的解決方案(https://stackoverflow.com/a/44350500/235055)更像我想要做的事。謝謝你回答:) – Shrayas