2014-05-16 57 views
4

我使用json.net來反序列化我的json字符串到我的模型。下面 是什麼,我想實現的,請指教什麼是最好的方式..自動選擇參數化構造函數,而JsonCovertor反序列化

當沒有數據我的反應看起來像下面 json string = "{\"message\":\"SUCCESS\",\"result\":null}"

結果最終被綁定到一個視圖。所以當響應爲空時,我想用默認模型值初始化我的視圖。因此想要在反序列化中調用Default構造函數。默認的構造函數如下所示。

public ProfileModel() 
    { 
     this.DefaultTab = DefaultTabOption.PROFILE; 
     this.DataLoadPosition = new DataLoadPositionOptionsModel(); 
     this.DataLayout = new DataLayoutOptionsModel(); 
     this.NAData = new NADataOptionsModel(); 
     this.DataTable = new DataDisplayOptionsModel(); 
    } 

但是,當有數據時,響應如下所示。

{"message":"SUCCESS","result":{"dataLayout":{"vertical":false},"dataLoadPosition":{"cell":"B2","cursorLocation":false},"dataTable":{"decimalPts":1},"defaultTab":"BROWSE","naData":{"custom":"","naDataOption":"FORWARDFILL"}}} 

在這種情況下,我想調用我的參數化構造函數,以便模型正確初始化。

反序列化代碼:

 using (StreamReader reader = new StreamReader(responseStream)) 
     { 
      var t = JsonConvert.DeserializeObject<T>(reader.ReadToEnd());     
      return t; 
     } 

其中T是initilialises多個模型我的主要模式。下面是參數化的構造函數。

public ProfileModel(DefaultTabOption defaultTabModel, 
        DataLoadPositionOptionsModel dataLoadPositionOption , 
        DataLayoutOptionsModel dataLayoutOptios , 
        NADataOptionsModel naDataOptions , 
        DataDisplayOptionsModel dataTableOptions) 
{ 
    this.DefaultTab = defaultTabModel; 
    this.DataLoadPosition = dataLoadPositionOption; 
    this.DataLayout = dataLayoutOptios; 
    this.NAData = naDataOptions; 
    this.DataTable = dataTableOptions; 
} 

什麼是反序列化的最佳方式,以便在null和parameterized時調用默認構造函數的時候調用not null。我試過ConstructorHandling,NullValueHandling,但我無法達到預期的效果。

回答

3

我有點簡化模型

public sealed class ProfileModel 
{ 
    public ProfileModel() 
    { 
     DataLayout = new DataLayoutOptionsModel(); 
    } 

    public ProfileModel(DataLayoutOptionsModel dataLayout) 
    { 
     DataLayout = dataLayout; 
    } 

    public DataLayoutOptionsModel DataLayout { get; private set; } 
} 

public sealed class DataLayoutOptionsModel 
{ 
    public bool Vertical { get; set; } 
} 

public class ResultModel 
{ 
    public string Message { get; set; } 
    public ProfileModel Result { get; set; } 
} 

要選擇具體的構造函數,你必須實現自定義JsonConverter,例如

public sealed class MyJsonConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return typeof(ProfileModel).IsAssignableFrom(objectType); 
    } 

    public override object ReadJson(JsonReader reader, 
     Type objectType, 
     object existingValue, 
     JsonSerializer serializer) 
    { 
     ProfileModel target; 
     JObject jObject = JObject.Load(reader); 

     JToken resultToken = jObject["Result"]; 
     //This is result null check 
     if (resultToken.Type == JTokenType.Null) 
     { 
      target = new ProfileModel(); 
     } 
     else 
     { 
      var optionsModel = resultToken["DataLayout"].ToObject<DataLayoutOptionsModel>(); 
      target = new ProfileModel(optionsModel); 
     } 

     serializer.Populate(jObject.CreateReader(), target); 
     return target; 
    } 

    public override void WriteJson(JsonWriter writer, 
     object value, 
     JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

所以,結果系列化的樣子:

[Fact] 
public void Test() 
{ 
    string tinyJsonl = "{\"Message\":\"SUCCESS\",\"Result\":null}"; 
    var defaultProfile = JsonConvert.DeserializeObject<ProfileModel>(tinyJsonl, new MyJsonConverter()); 
    Assert.False(defaultProfile.DataLayout.Vertical); 

    string fullJson = "{\"Message\":\"SUCCESS\",\"Result\":{\"DataLayout\":{\"Vertical\":true}}}"; 
    var customProfile = JsonConvert.DeserializeObject<ProfileModel>(fullJson, new MyJsonConverter()); 
    Assert.True(customProfile.DataLayout.Vertical); 
} 
相關問題